[libgda] Switched to SQlite 3.8.0.2 and SlqCipher 3.0.0



commit 70e44aa0e21c74bf1a3968454db1bd77c546d590
Author: Vivien Malerba <malerba gnome-db org>
Date:   Mon Nov 11 13:53:13 2013 +0100

    Switched to SQlite 3.8.0.2 and SlqCipher 3.0.0

 libgda/sqlite/sqlite-src/PragmasPatch |    6 +-
 libgda/sqlite/sqlite-src/sqlite3.c    | 8621 +++--
 libgda/sqlite/sqlite-src/sqlite3.h    |  124 +-
 providers/sqlcipher/sqlcipher.patch   |62995 +--------------------------------
 4 files changed, 5860 insertions(+), 65886 deletions(-)
---
diff --git a/libgda/sqlite/sqlite-src/PragmasPatch b/libgda/sqlite/sqlite-src/PragmasPatch
index a8f87f9..decd9ea 100644
--- a/libgda/sqlite/sqlite-src/PragmasPatch
+++ b/libgda/sqlite/sqlite-src/PragmasPatch
@@ -1,6 +1,6 @@
---- sqlite3.c.orig     2013-05-20 12:56:34.000000000 +0200
-+++ sqlite3.c  2013-06-30 15:08:52.994949387 +0200
-@@ -94348,6 +94348,60 @@
+--- sqlite3.c.orig     2013-09-04 00:26:22.000000000 +0200
++++ sqlite3.c  2013-11-09 12:39:57.315522927 +0100
+@@ -94739,6 +94739,60 @@
  
  #ifndef SQLITE_OMIT_SCHEMA_PRAGMAS
    /*
diff --git a/libgda/sqlite/sqlite-src/sqlite3.c b/libgda/sqlite/sqlite-src/sqlite3.c
index 3e7d7a5..af83417 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.7.17.  By combining all the individual C code files into this 
+** version 3.8.0.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
@@ -354,7 +354,7 @@
 ** 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
-** level of threadsafety.  2 means the libary is multithreaded - multiple
+** level of threadsafety.  2 means the library is multithreaded - multiple
 ** threads can use SQLite as long as no two threads try to use the same
 ** database connection at the same time.
 **
@@ -401,9 +401,6 @@
 ** will cause HeapValidate to be called.  If heap validation should fail, an
 ** assertion will be triggered.
 **
-** (Historical note:  There used to be several other options, but we've
-** pared it down to just these three.)
-**
 ** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as
 ** the default.
 */
@@ -433,27 +430,12 @@
 
 /*
 ** We need to define _XOPEN_SOURCE as follows in order to enable
-** recursive mutexes on most Unix systems.  But Mac OS X is different.
-** The _XOPEN_SOURCE define causes problems for Mac OS X we are told,
-** so it is omitted there.  See ticket #2673.
-**
-** Later we learn that _XOPEN_SOURCE is poorly or incorrectly
-** implemented on some systems.  So we avoid defining it at all
-** if it is already defined or if it is unneeded because we are
-** not doing a threadsafe build.  Ticket #2681.
-**
-** See also ticket #2741.
-*/
-#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) \
- && !defined(__APPLE__) && SQLITE_THREADSAFE
-#  define _XOPEN_SOURCE 500  /* Needed to enable pthread recursive mutexes */
-#endif
-
-/*
-** The TCL headers are only needed when compiling the TCL bindings.
+** recursive mutexes on most Unix systems and fchmod() on OpenBSD.
+** But _XOPEN_SOURCE define causes problems for Mac OS X, so omit
+** it.
 */
-#if defined(SQLITE_TCL) || defined(TCLSH)
-# include <tcl.h>
+#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__)
+#  define _XOPEN_SOURCE 600
 #endif
 
 /*
@@ -461,8 +443,8 @@
 ** defined(NDEBUG)==!defined(SQLITE_DEBUG).  If this is not currently true,
 ** make it true by defining or undefining NDEBUG.
 **
-** Setting NDEBUG makes the code smaller and run faster by disabling the
-** number assert() statements in the code.  So we want the default action
+** Setting NDEBUG makes the code smaller and faster by disabling the
+** assert() statements in the code.  So we want the default action
 ** to be for NDEBUG to be set and NDEBUG to be undefined only if SQLITE_DEBUG
 ** is set.  Thus NDEBUG becomes an opt-in rather than an opt-out
 ** feature.
@@ -532,7 +514,7 @@ SQLITE_PRIVATE   void sqlite3Coverage(int);
 ** In other words, ALWAYS and NEVER are added for defensive code.
 **
 ** When doing coverage testing ALWAYS and NEVER are hard-coded to
-** be true and false so that the unreachable code then specify will
+** be true and false so that the unreachable code they specify will
 ** not be counted as untested code.
 */
 #if defined(SQLITE_COVERAGE_TEST)
@@ -556,16 +538,12 @@ SQLITE_PRIVATE   void sqlite3Coverage(int);
 /*
 ** The macro unlikely() is a hint that surrounds a boolean
 ** expression that is usually false.  Macro likely() surrounds
-** a boolean expression that is usually true.  GCC is able to
-** use these hints to generate better code, sometimes.
+** a boolean expression that is usually true.  These hints could,
+** in theory, be used by the compiler to generate better code, but
+** currently they are just comments for human readers.
 */
-#if defined(__GNUC__) && 0
-# define likely(X)    __builtin_expect((X),1)
-# define unlikely(X)  __builtin_expect((X),0)
-#else
-# define likely(X)    !!(X)
-# define unlikely(X)  !!(X)
-#endif
+#define likely(X)    (X)
+#define unlikely(X)  (X)
 
 /************** Include sqlite3.h in the middle of sqliteInt.h ***************/
 /************** Begin file sqlite3.h *****************************************/
@@ -678,9 +656,9 @@ extern "C" {
 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
 ** [sqlite_version()] and [sqlite_source_id()].
 */
-#define SQLITE_VERSION        "3.7.17"
-#define SQLITE_VERSION_NUMBER 3007017
-#define SQLITE_SOURCE_ID      "2013-05-20 00:56:22 118a3b35693b134d56ebd780123b7fd6f1497668"
+#define SQLITE_VERSION        "3.8.0.2"
+#define SQLITE_VERSION_NUMBER 3008000
+#define SQLITE_SOURCE_ID      "2013-09-03 17:11:13 7dd4968f235d6e1ca9547cda9cf3bd570e1609ef"
 
 /*
 ** CAPI3REF: Run-Time Library Version Numbers
@@ -1049,8 +1027,10 @@ SQLITE_API int sqlite3_exec(
 #define SQLITE_IOERR_SEEK              (SQLITE_IOERR | (22<<8))
 #define SQLITE_IOERR_DELETE_NOENT      (SQLITE_IOERR | (23<<8))
 #define SQLITE_IOERR_MMAP              (SQLITE_IOERR | (24<<8))
+#define SQLITE_IOERR_GETTEMPPATH       (SQLITE_IOERR | (25<<8))
 #define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
 #define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
+#define SQLITE_BUSY_SNAPSHOT           (SQLITE_BUSY   |  (2<<8))
 #define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
 #define SQLITE_CANTOPEN_ISDIR          (SQLITE_CANTOPEN | (2<<8))
 #define SQLITE_CANTOPEN_FULLPATH       (SQLITE_CANTOPEN | (3<<8))
@@ -1070,6 +1050,7 @@ SQLITE_API int sqlite3_exec(
 #define SQLITE_CONSTRAINT_VTAB         (SQLITE_CONSTRAINT | (9<<8))
 #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))
 
 /*
 ** CAPI3REF: Flags For File Open Operations
@@ -3128,9 +3109,10 @@ SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
 ** interface is to keep a GUI updated during a large query.
 **
 ** ^The parameter P is passed through as the only parameter to the 
-** callback function X.  ^The parameter N is the number of 
+** callback function X.  ^The parameter N is the approximate number of 
 ** [virtual machine instructions] that are evaluated between successive
-** invocations of the callback X.
+** invocations of the callback X.  ^If N is less than one then the progress
+** handler is disabled.
 **
 ** ^Only a single progress handler may be defined at one time per
 ** [database connection]; setting a new progress handler cancels the
@@ -4750,41 +4732,49 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
 /*
 ** CAPI3REF: Function Auxiliary Data
 **
-** The following two functions may be used by scalar SQL functions to
+** These functions may be used by (non-aggregate) SQL functions to
 ** associate metadata with argument values. If the same value is passed to
 ** multiple invocations of the same SQL function during query execution, under
-** some circumstances the associated metadata may be preserved. This may
-** be used, for example, to add a regular-expression matching scalar
-** function. The compiled version of the regular expression is stored as
-** metadata associated with the SQL value passed as the regular expression
-** pattern.  The compiled regular expression can be reused on multiple
-** invocations of the same function so that the original pattern string
-** does not need to be recompiled on each invocation.
+** some circumstances the associated metadata may be preserved.  An example
+** of where this might be useful is in a regular-expression matching
+** function. The compiled version of the regular expression can be stored as
+** metadata associated with the pattern string.  
+** Then as long as the pattern string remains the same,
+** the compiled regular expression can be reused on multiple
+** invocations of the same function.
 **
 ** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
 ** associated by the sqlite3_set_auxdata() function with the Nth argument
-** value to the application-defined function. ^If no metadata has been ever
-** been set for the Nth argument of the function, or if the corresponding
-** function parameter has changed since the meta-data was set,
-** then sqlite3_get_auxdata() returns a NULL pointer.
-**
-** ^The sqlite3_set_auxdata() interface saves the metadata
-** pointed to by its 3rd parameter as the metadata for the N-th
-** argument of the application-defined function.  Subsequent
-** calls to sqlite3_get_auxdata() might return this data, if it has
-** not been destroyed.
-** ^If it is not NULL, SQLite will invoke the destructor
-** function given by the 4th parameter to sqlite3_set_auxdata() on
-** the metadata when the corresponding function parameter changes
-** or when the SQL statement completes, whichever comes first.
-**
-** SQLite is free to call the destructor and drop metadata on any
-** parameter of any function at any time.  ^The only guarantee is that
-** the destructor will be called before the metadata is dropped.
+** value to the application-defined function. ^If there is no metadata
+** associated with the function argument, this sqlite3_get_auxdata() interface
+** returns a NULL pointer.
+**
+** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
+** argument of the application-defined function.  ^Subsequent
+** calls to sqlite3_get_auxdata(C,N) return P from the most recent
+** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or
+** NULL if the metadata has been discarded.
+** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL,
+** SQLite will invoke the destructor function X with parameter P exactly
+** once, when the metadata is discarded.
+** SQLite is free to discard the metadata at any time, including: <ul>
+** <li> when the corresponding function parameter changes, or
+** <li> when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
+**      SQL statement, or
+** <li> when sqlite3_set_auxdata() is invoked again on the same parameter, or
+** <li> during the original sqlite3_set_auxdata() call when a memory 
+**      allocation error occurs. </ul>)^
+**
+** Note the last bullet in particular.  The destructor X in 
+** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
+** sqlite3_set_auxdata() interface even returns.  Hence sqlite3_set_auxdata()
+** should be called near the end of the function implementation and the
+** function implementation should not make any use of P after
+** sqlite3_set_auxdata() has been called.
 **
 ** ^(In practice, metadata is preserved between function calls for
-** expressions that are constant at compile time. This includes literal
-** values and [parameters].)^
+** function parameters that are compile-time constants, including literal
+** values and [parameters] and expressions composed from the same.)^
 **
 ** These routines must be called from the same thread in which
 ** the SQL function is running.
@@ -5089,6 +5079,11 @@ SQLITE_API int sqlite3_key(
   sqlite3 *db,                   /* Database to be rekeyed */
   const void *pKey, int nKey     /* The key */
 );
+SQLITE_API int sqlite3_key_v2(
+  sqlite3 *db,                   /* Database to be rekeyed */
+  const char *zDbName,           /* Name of the database */
+  const void *pKey, int nKey     /* The key */
+);
 
 /*
 ** Change the key on an open database.  If the current database is not
@@ -5102,6 +5097,11 @@ SQLITE_API int sqlite3_rekey(
   sqlite3 *db,                   /* Database to be rekeyed */
   const void *pKey, int nKey     /* The new key */
 );
+SQLITE_API int sqlite3_rekey_v2(
+  sqlite3 *db,                   /* Database to be rekeyed */
+  const char *zDbName,           /* Name of the database */
+  const void *pKey, int nKey     /* The new key */
+);
 
 /*
 ** Specify the activation key for a SEE database.  Unless 
@@ -5687,11 +5687,24 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
 ** on the list of automatic extensions is a harmless no-op. ^No entry point
 ** will be called more than once for each database connection that is opened.
 **
-** See also: [sqlite3_reset_auto_extension()].
+** See also: [sqlite3_reset_auto_extension()]
+** and [sqlite3_cancel_auto_extension()]
 */
 SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
 
 /*
+** CAPI3REF: Cancel Automatic Extension Loading
+**
+** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the
+** initialization routine X that was registered using a prior call to
+** [sqlite3_auto_extension(X)].  ^The [sqlite3_cancel_auto_extension(X)]
+** routine returns 1 if initialization routine X was successfully 
+** 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));
+
+/*
 ** CAPI3REF: Reset Automatic Extension Loading
 **
 ** ^This interface disables all automatic extensions previously
@@ -6803,6 +6816,12 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
 ** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
 ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
 ** </dd>
+**
+** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
+** <dd>This parameter returns zero for the current value if and only if
+** all foreign key constraints (deferred or immediate) have been
+** resolved.)^  ^The highwater mark is always 0.
+** </dd>
 ** </dl>
 */
 #define SQLITE_DBSTATUS_LOOKASIDE_USED       0
@@ -6815,7 +6834,8 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
 #define SQLITE_DBSTATUS_CACHE_HIT            7
 #define SQLITE_DBSTATUS_CACHE_MISS           8
 #define SQLITE_DBSTATUS_CACHE_WRITE          9
-#define SQLITE_DBSTATUS_MAX                  9   /* Largest defined DBSTATUS */
+#define SQLITE_DBSTATUS_DEFERRED_FKS        10
+#define SQLITE_DBSTATUS_MAX                 10   /* Largest defined DBSTATUS */
 
 
 /*
@@ -6869,11 +6889,21 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
 ** A non-zero value in this counter may indicate an opportunity to
 ** improvement performance by adding permanent indices that do not
 ** need to be reinitialized each time the statement is run.</dd>
+**
+** [[SQLITE_STMTSTATUS_VM_STEP]] <dt>SQLITE_STMTSTATUS_VM_STEP</dt>
+** <dd>^This is the number of virtual machine operations executed
+** by the prepared statement if that number is less than or equal
+** to 2147483647.  The number of virtual machine operations can be 
+** used as a proxy for the total work done by the prepared statement.
+** If the number of virtual machine operations exceeds 2147483647
+** then the value returned by this statement status code is undefined.
+** </dd>
 ** </dl>
 */
 #define SQLITE_STMTSTATUS_FULLSCAN_STEP     1
 #define SQLITE_STMTSTATUS_SORT              2
 #define SQLITE_STMTSTATUS_AUTOINDEX         3
+#define SQLITE_STMTSTATUS_VM_STEP           4
 
 /*
 ** CAPI3REF: Custom Page Cache Object
@@ -7752,7 +7782,7 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
 #if 0
 }  /* End of the 'extern "C"' block */
 #endif
-#endif
+#endif /* _SQLITE3_H_ */
 
 /*
 ** 2010 August 30
@@ -8154,6 +8184,12 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
 #endif
 
 /*
+** Macros to compute minimum and maximum of two numbers.
+*/
+#define MIN(A,B) ((A)<(B)?(A):(B))
+#define MAX(A,B) ((A)>(B)?(A):(B))
+
+/*
 ** Check to see if this machine uses EBCDIC.  (Yes, believe it or
 ** not, there are still machines out there that use EBCDIC.)
 */
@@ -8478,9 +8514,7 @@ typedef struct UnpackedRecord UnpackedRecord;
 typedef struct VTable VTable;
 typedef struct VtabCtx VtabCtx;
 typedef struct Walker Walker;
-typedef struct WherePlan WherePlan;
 typedef struct WhereInfo WhereInfo;
-typedef struct WhereLevel WhereLevel;
 
 /*
 ** Defer sourcing vdbe.h and btree.h until after the "u8" and 
@@ -8555,7 +8589,7 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
 SQLITE_PRIVATE int sqlite3BtreeClose(Btree*);
 SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int);
 SQLITE_PRIVATE int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64);
-SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(Btree*,int,int,int);
+SQLITE_PRIVATE int sqlite3BtreeSetPagerFlags(Btree*,unsigned);
 SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree*);
 SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
 SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*);
@@ -8779,7 +8813,6 @@ typedef struct Vdbe Vdbe;
 ** The names of the following types declared in vdbeInt.h are required
 ** for the VdbeOp definition.
 */
-typedef struct VdbeFunc VdbeFunc;
 typedef struct Mem Mem;
 typedef struct SubProgram SubProgram;
 
@@ -8803,7 +8836,6 @@ struct VdbeOp {
     i64 *pI64;             /* Used when p4type is P4_INT64 */
     double *pReal;         /* Used when p4type is P4_REAL */
     FuncDef *pFunc;        /* Used when p4type is P4_FUNCDEF */
-    VdbeFunc *pVdbeFunc;   /* Used when p4type is P4_VDBEFUNC */
     CollSeq *pColl;        /* Used when p4type is P4_COLLSEQ */
     Mem *pMem;             /* Used when p4type is P4_MEM */
     VTable *pVtab;         /* Used when p4type is P4_VTAB */
@@ -8857,7 +8889,6 @@ typedef struct VdbeOpList VdbeOpList;
 #define P4_COLLSEQ  (-4)  /* P4 is a pointer to a CollSeq structure */
 #define P4_FUNCDEF  (-5)  /* P4 is a pointer to a FuncDef structure */
 #define P4_KEYINFO  (-6)  /* P4 is a pointer to a KeyInfo structure */
-#define P4_VDBEFUNC (-7)  /* P4 is a pointer to a VdbeFunc structure */
 #define P4_MEM      (-8)  /* P4 is a pointer to a Mem*    structure */
 #define P4_TRANSIENT  0   /* P4 is a pointer to a transient string */
 #define P4_VTAB     (-10) /* P4 is a pointer to an sqlite3_vtab structure */
@@ -8914,151 +8945,151 @@ typedef struct VdbeOpList VdbeOpList;
 /************** Begin file opcodes.h *****************************************/
 /* Automatically generated.  Do not edit */
 /* See the mkopcodeh.awk script for details */
-#define OP_Goto                                 1
-#define OP_Gosub                                2
-#define OP_Return                               3
-#define OP_Yield                                4
-#define OP_HaltIfNull                           5
-#define OP_Halt                                 6
-#define OP_Integer                              7
-#define OP_Int64                                8
-#define OP_Real                               130   /* same as TK_FLOAT    */
-#define OP_String8                             94   /* same as TK_STRING   */
-#define OP_String                               9
-#define OP_Null                                10
-#define OP_Blob                                11
-#define OP_Variable                            12
-#define OP_Move                                13
-#define OP_Copy                                14
-#define OP_SCopy                               15
-#define OP_ResultRow                           16
-#define OP_Concat                              91   /* same as TK_CONCAT   */
+#define OP_Function                             1
+#define OP_Savepoint                            2
+#define OP_AutoCommit                           3
+#define OP_Transaction                          4
+#define OP_SorterNext                           5
+#define OP_Prev                                 6
+#define OP_Next                                 7
+#define OP_AggStep                              8
+#define OP_Checkpoint                           9
+#define OP_JournalMode                         10
+#define OP_Vacuum                              11
+#define OP_VFilter                             12
+#define OP_VUpdate                             13
+#define OP_Goto                                14
+#define OP_Gosub                               15
+#define OP_Return                              16
+#define OP_Yield                               17
+#define OP_HaltIfNull                          18
+#define OP_Not                                 19   /* same as TK_NOT      */
+#define OP_Halt                                20
+#define OP_Integer                             21
+#define OP_Int64                               22
+#define OP_String                              23
+#define OP_Null                                24
+#define OP_Blob                                25
+#define OP_Variable                            26
+#define OP_Move                                27
+#define OP_Copy                                28
+#define OP_SCopy                               29
+#define OP_ResultRow                           30
+#define OP_CollSeq                             31
+#define OP_AddImm                              32
+#define OP_MustBeInt                           33
+#define OP_RealAffinity                        34
+#define OP_Permutation                         35
+#define OP_Compare                             36
+#define OP_Jump                                37
+#define OP_Once                                38
+#define OP_If                                  39
+#define OP_IfNot                               40
+#define OP_Column                              41
+#define OP_Affinity                            42
+#define OP_MakeRecord                          43
+#define OP_Count                               44
+#define OP_ReadCookie                          45
+#define OP_SetCookie                           46
+#define OP_VerifyCookie                        47
+#define OP_OpenRead                            48
+#define OP_OpenWrite                           49
+#define OP_OpenAutoindex                       50
+#define OP_OpenEphemeral                       51
+#define OP_SorterOpen                          52
+#define OP_OpenPseudo                          53
+#define OP_Close                               54
+#define OP_SeekLt                              55
+#define OP_SeekLe                              56
+#define OP_SeekGe                              57
+#define OP_SeekGt                              58
+#define OP_Seek                                59
+#define OP_NotFound                            60
+#define OP_Found                               61
+#define OP_IsUnique                            62
+#define OP_NotExists                           63
+#define OP_Sequence                            64
+#define OP_NewRowid                            65
+#define OP_Insert                              66
+#define OP_InsertInt                           67
+#define OP_Or                                  68   /* same as TK_OR       */
+#define OP_And                                 69   /* same as TK_AND      */
+#define OP_Delete                              70
+#define OP_ResetCount                          71
+#define OP_SorterCompare                       72
+#define OP_IsNull                              73   /* same as TK_ISNULL   */
+#define OP_NotNull                             74   /* same as TK_NOTNULL  */
+#define OP_Ne                                  75   /* same as TK_NE       */
+#define OP_Eq                                  76   /* same as TK_EQ       */
+#define OP_Gt                                  77   /* same as TK_GT       */
+#define OP_Le                                  78   /* same as TK_LE       */
+#define OP_Lt                                  79   /* same as TK_LT       */
+#define OP_Ge                                  80   /* same as TK_GE       */
+#define OP_SorterData                          81
+#define OP_BitAnd                              82   /* same as TK_BITAND   */
+#define OP_BitOr                               83   /* same as TK_BITOR    */
+#define OP_ShiftLeft                           84   /* same as TK_LSHIFT   */
+#define OP_ShiftRight                          85   /* same as TK_RSHIFT   */
 #define OP_Add                                 86   /* same as TK_PLUS     */
 #define OP_Subtract                            87   /* same as TK_MINUS    */
 #define OP_Multiply                            88   /* same as TK_STAR     */
 #define OP_Divide                              89   /* same as TK_SLASH    */
 #define OP_Remainder                           90   /* same as TK_REM      */
-#define OP_CollSeq                             17
-#define OP_Function                            18
-#define OP_BitAnd                              82   /* same as TK_BITAND   */
-#define OP_BitOr                               83   /* same as TK_BITOR    */
-#define OP_ShiftLeft                           84   /* same as TK_LSHIFT   */
-#define OP_ShiftRight                          85   /* same as TK_RSHIFT   */
-#define OP_AddImm                              20
-#define OP_MustBeInt                           21
-#define OP_RealAffinity                        22
+#define OP_Concat                              91   /* same as TK_CONCAT   */
+#define OP_RowKey                              92
+#define OP_BitNot                              93   /* same as TK_BITNOT   */
+#define OP_String8                             94   /* same as TK_STRING   */
+#define OP_RowData                             95
+#define OP_Rowid                               96
+#define OP_NullRow                             97
+#define OP_Last                                98
+#define OP_SorterSort                          99
+#define OP_Sort                               100
+#define OP_Rewind                             101
+#define OP_SorterInsert                       102
+#define OP_IdxInsert                          103
+#define OP_IdxDelete                          104
+#define OP_IdxRowid                           105
+#define OP_IdxLT                              106
+#define OP_IdxGE                              107
+#define OP_Destroy                            108
+#define OP_Clear                              109
+#define OP_CreateIndex                        110
+#define OP_CreateTable                        111
+#define OP_ParseSchema                        112
+#define OP_LoadAnalysis                       113
+#define OP_DropTable                          114
+#define OP_DropIndex                          115
+#define OP_DropTrigger                        116
+#define OP_IntegrityCk                        117
+#define OP_RowSetAdd                          118
+#define OP_RowSetRead                         119
+#define OP_RowSetTest                         120
+#define OP_Program                            121
+#define OP_Param                              122
+#define OP_FkCounter                          123
+#define OP_FkIfZero                           124
+#define OP_MemMax                             125
+#define OP_IfPos                              126
+#define OP_IfNeg                              127
+#define OP_IfZero                             128
+#define OP_AggFinal                           129
+#define OP_Real                               130   /* same as TK_FLOAT    */
+#define OP_IncrVacuum                         131
+#define OP_Expire                             132
+#define OP_TableLock                          133
+#define OP_VBegin                             134
+#define OP_VCreate                            135
+#define OP_VDestroy                           136
+#define OP_VOpen                              137
+#define OP_VColumn                            138
+#define OP_VNext                              139
+#define OP_VRename                            140
 #define OP_ToText                             141   /* same as TK_TO_TEXT  */
 #define OP_ToBlob                             142   /* same as TK_TO_BLOB  */
 #define OP_ToNumeric                          143   /* same as TK_TO_NUMERIC*/
 #define OP_ToInt                              144   /* same as TK_TO_INT   */
 #define OP_ToReal                             145   /* same as TK_TO_REAL  */
-#define OP_Eq                                  76   /* same as TK_EQ       */
-#define OP_Ne                                  75   /* same as TK_NE       */
-#define OP_Lt                                  79   /* same as TK_LT       */
-#define OP_Le                                  78   /* same as TK_LE       */
-#define OP_Gt                                  77   /* same as TK_GT       */
-#define OP_Ge                                  80   /* same as TK_GE       */
-#define OP_Permutation                         23
-#define OP_Compare                             24
-#define OP_Jump                                25
-#define OP_And                                 69   /* same as TK_AND      */
-#define OP_Or                                  68   /* same as TK_OR       */
-#define OP_Not                                 19   /* same as TK_NOT      */
-#define OP_BitNot                              93   /* same as TK_BITNOT   */
-#define OP_Once                                26
-#define OP_If                                  27
-#define OP_IfNot                               28
-#define OP_IsNull                              73   /* same as TK_ISNULL   */
-#define OP_NotNull                             74   /* same as TK_NOTNULL  */
-#define OP_Column                              29
-#define OP_Affinity                            30
-#define OP_MakeRecord                          31
-#define OP_Count                               32
-#define OP_Savepoint                           33
-#define OP_AutoCommit                          34
-#define OP_Transaction                         35
-#define OP_ReadCookie                          36
-#define OP_SetCookie                           37
-#define OP_VerifyCookie                        38
-#define OP_OpenRead                            39
-#define OP_OpenWrite                           40
-#define OP_OpenAutoindex                       41
-#define OP_OpenEphemeral                       42
-#define OP_SorterOpen                          43
-#define OP_OpenPseudo                          44
-#define OP_Close                               45
-#define OP_SeekLt                              46
-#define OP_SeekLe                              47
-#define OP_SeekGe                              48
-#define OP_SeekGt                              49
-#define OP_Seek                                50
-#define OP_NotFound                            51
-#define OP_Found                               52
-#define OP_IsUnique                            53
-#define OP_NotExists                           54
-#define OP_Sequence                            55
-#define OP_NewRowid                            56
-#define OP_Insert                              57
-#define OP_InsertInt                           58
-#define OP_Delete                              59
-#define OP_ResetCount                          60
-#define OP_SorterCompare                       61
-#define OP_SorterData                          62
-#define OP_RowKey                              63
-#define OP_RowData                             64
-#define OP_Rowid                               65
-#define OP_NullRow                             66
-#define OP_Last                                67
-#define OP_SorterSort                          70
-#define OP_Sort                                71
-#define OP_Rewind                              72
-#define OP_SorterNext                          81
-#define OP_Prev                                92
-#define OP_Next                                95
-#define OP_SorterInsert                        96
-#define OP_IdxInsert                           97
-#define OP_IdxDelete                           98
-#define OP_IdxRowid                            99
-#define OP_IdxLT                              100
-#define OP_IdxGE                              101
-#define OP_Destroy                            102
-#define OP_Clear                              103
-#define OP_CreateIndex                        104
-#define OP_CreateTable                        105
-#define OP_ParseSchema                        106
-#define OP_LoadAnalysis                       107
-#define OP_DropTable                          108
-#define OP_DropIndex                          109
-#define OP_DropTrigger                        110
-#define OP_IntegrityCk                        111
-#define OP_RowSetAdd                          112
-#define OP_RowSetRead                         113
-#define OP_RowSetTest                         114
-#define OP_Program                            115
-#define OP_Param                              116
-#define OP_FkCounter                          117
-#define OP_FkIfZero                           118
-#define OP_MemMax                             119
-#define OP_IfPos                              120
-#define OP_IfNeg                              121
-#define OP_IfZero                             122
-#define OP_AggStep                            123
-#define OP_AggFinal                           124
-#define OP_Checkpoint                         125
-#define OP_JournalMode                        126
-#define OP_Vacuum                             127
-#define OP_IncrVacuum                         128
-#define OP_Expire                             129
-#define OP_TableLock                          131
-#define OP_VBegin                             132
-#define OP_VCreate                            133
-#define OP_VDestroy                           134
-#define OP_VOpen                              135
-#define OP_VFilter                            136
-#define OP_VColumn                            137
-#define OP_VNext                              138
-#define OP_VRename                            139
-#define OP_VUpdate                            140
 #define OP_Pagecount                          146
 #define OP_MaxPgcnt                           147
 #define OP_Trace                              148
@@ -9078,24 +9109,24 @@ typedef struct VdbeOpList VdbeOpList;
 #define OPFLG_OUT2            0x0020  /* out2:  P2 is an output */
 #define OPFLG_OUT3            0x0040  /* out3:  P3 is an output */
 #define OPFLG_INITIALIZER {\
-/*   0 */ 0x00, 0x01, 0x01, 0x04, 0x04, 0x10, 0x00, 0x02,\
-/*   8 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x24,\
-/*  16 */ 0x00, 0x00, 0x00, 0x24, 0x04, 0x05, 0x04, 0x00,\
-/*  24 */ 0x00, 0x01, 0x01, 0x05, 0x05, 0x00, 0x00, 0x00,\
-/*  32 */ 0x02, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,\
-/*  40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11,\
-/*  48 */ 0x11, 0x11, 0x08, 0x11, 0x11, 0x11, 0x11, 0x02,\
-/*  56 */ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/*  64 */ 0x00, 0x02, 0x00, 0x01, 0x4c, 0x4c, 0x01, 0x01,\
-/*  72 */ 0x01, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\
-/*  80 */ 0x15, 0x01, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\
-/*  88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x01, 0x24, 0x02, 0x01,\
-/*  96 */ 0x08, 0x08, 0x00, 0x02, 0x01, 0x01, 0x02, 0x00,\
-/* 104 */ 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 112 */ 0x0c, 0x45, 0x15, 0x01, 0x02, 0x00, 0x01, 0x08,\
-/* 120 */ 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00,\
-/* 128 */ 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 136 */ 0x01, 0x00, 0x01, 0x00, 0x00, 0x04, 0x04, 0x04,\
+/*   0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,\
+/*   8 */ 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x01,\
+/*  16 */ 0x04, 0x04, 0x10, 0x24, 0x00, 0x02, 0x02, 0x02,\
+/*  24 */ 0x02, 0x02, 0x02, 0x00, 0x00, 0x24, 0x00, 0x00,\
+/*  32 */ 0x04, 0x05, 0x04, 0x00, 0x00, 0x01, 0x01, 0x05,\
+/*  40 */ 0x05, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00,\
+/*  48 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,\
+/*  56 */ 0x11, 0x11, 0x11, 0x08, 0x11, 0x11, 0x11, 0x11,\
+/*  64 */ 0x02, 0x02, 0x00, 0x00, 0x4c, 0x4c, 0x00, 0x00,\
+/*  72 */ 0x00, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\
+/*  80 */ 0x15, 0x00, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\
+/*  88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x00, 0x24, 0x02, 0x00,\
+/*  96 */ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x08, 0x08,\
+/* 104 */ 0x00, 0x02, 0x01, 0x01, 0x02, 0x00, 0x02, 0x02,\
+/* 112 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x45,\
+/* 120 */ 0x15, 0x01, 0x02, 0x00, 0x01, 0x08, 0x05, 0x05,\
+/* 128 */ 0x05, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,\
+/* 136 */ 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x04, 0x04,\
 /* 144 */ 0x04, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00,}
 
 /************** End of opcodes.h *********************************************/
@@ -9145,7 +9176,7 @@ SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*);
 SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, int);
 SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*);
 SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*);
-SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetValue(Vdbe*, int, u8);
+SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8);
 SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int);
 #ifndef SQLITE_OMIT_TRACE
 SQLITE_PRIVATE   char *sqlite3VdbeExpandSql(Vdbe*, const char*);
@@ -9259,8 +9290,20 @@ typedef struct PgHdr DbPage;
 /*
 ** Flags that make up the mask passed to sqlite3PagerAcquire().
 */
-#define PAGER_ACQUIRE_NOCONTENT     0x01  /* Do not load data from disk */
-#define PAGER_ACQUIRE_READONLY      0x02  /* Read-only page is acceptable */
+#define PAGER_GET_NOCONTENT     0x01  /* Do not load data from disk */
+#define PAGER_GET_READONLY      0x02  /* Read-only page is acceptable */
+
+/*
+** Flags for sqlite3PagerSetFlags()
+*/
+#define PAGER_SYNCHRONOUS_OFF       0x01  /* PRAGMA synchronous=OFF */
+#define PAGER_SYNCHRONOUS_NORMAL    0x02  /* PRAGMA synchronous=NORMAL */
+#define PAGER_SYNCHRONOUS_FULL      0x03  /* PRAGMA synchronous=FULL */
+#define PAGER_SYNCHRONOUS_MASK      0x03  /* Mask for three values above */
+#define PAGER_FULLFSYNC             0x04  /* PRAGMA fullfsync=ON */
+#define PAGER_CKPT_FULLFSYNC        0x08  /* PRAGMA checkpoint_fullfsync=ON */
+#define PAGER_CACHESPILL            0x10  /* PRAGMA cache_spill=ON */
+#define PAGER_FLAGS_MASK            0x1c  /* All above except SYNCHRONOUS */
 
 /*
 ** The remainder of this file contains the declarations of the functions
@@ -9288,7 +9331,7 @@ SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager*, int);
 SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int);
 SQLITE_PRIVATE void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64);
 SQLITE_PRIVATE void sqlite3PagerShrink(Pager*);
-SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(Pager*,int,int,int);
+SQLITE_PRIVATE void sqlite3PagerSetFlags(Pager*,unsigned);
 SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *, int);
 SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *, int);
 SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager*);
@@ -9917,7 +9960,6 @@ SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *);
 struct Db {
   char *zName;         /* Name of this database */
   Btree *pBt;          /* The B*Tree structure for this database file */
-  u8 inTrans;          /* 0: not writable.  1: Transaction.  2: Checkpoint */
   u8 safety_level;     /* How aggressive at syncing data to disk */
   Schema *pSchema;     /* Pointer to database schema (possibly shared) */
 };
@@ -10063,9 +10105,10 @@ struct sqlite3 {
     u8 busy;                    /* TRUE if currently initializing */
     u8 orphanTrigger;           /* Last statement is orphaned TEMP trigger */
   } init;
-  int activeVdbeCnt;            /* Number of VDBEs currently executing */
-  int writeVdbeCnt;             /* Number of active VDBEs that are writing */
-  int vdbeExecCnt;              /* Number of nested calls to VdbeExec() */
+  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 nExtension;               /* Number of loaded extensions */
   void **aExtension;            /* Array of shared library handles */
   void (*xTrace)(void*,const char*);        /* Trace function */
@@ -10101,7 +10144,7 @@ struct sqlite3 {
 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
   int (*xProgress)(void *);     /* The progress callback */
   void *pProgressArg;           /* Argument to the progress callback */
-  int nProgressOps;             /* Number of opcodes for progress callback */
+  unsigned nProgressOps;        /* Number of opcodes for progress callback */
 #endif
 #ifndef SQLITE_OMIT_VIRTUALTABLE
   int nVTrans;                  /* Allocated size of aVTrans */
@@ -10119,6 +10162,7 @@ struct sqlite3 {
   int nSavepoint;               /* Number of non-transaction savepoints */
   int nStatement;               /* Number of nested statement-transactions  */
   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
@@ -10150,30 +10194,34 @@ struct sqlite3 {
 */
 #define SQLITE_VdbeTrace      0x00000001  /* True to trace VDBE execution */
 #define SQLITE_InternChanges  0x00000002  /* Uncommitted Hash table changes */
-#define SQLITE_FullColNames   0x00000004  /* Show full column names on SELECT */
-#define SQLITE_ShortColNames  0x00000008  /* Show short columns names */
-#define SQLITE_CountRows      0x00000010  /* Count rows changed by INSERT, */
+#define SQLITE_FullFSync      0x00000004  /* Use full fsync on the backend */
+#define SQLITE_CkptFullFSync  0x00000008  /* Use full fsync for checkpoint */
+#define SQLITE_CacheSpill     0x00000010  /* OK to spill pager cache */
+#define SQLITE_FullColNames   0x00000020  /* Show full column names on SELECT */
+#define SQLITE_ShortColNames  0x00000040  /* Show short columns names */
+#define SQLITE_CountRows      0x00000080  /* Count rows changed by INSERT, */
                                           /*   DELETE, or UPDATE and return */
                                           /*   the count using a callback. */
-#define SQLITE_NullCallback   0x00000020  /* Invoke the callback once if the */
+#define SQLITE_NullCallback   0x00000100  /* Invoke the callback once if the */
                                           /*   result set is empty */
-#define SQLITE_SqlTrace       0x00000040  /* Debug print SQL as it executes */
-#define SQLITE_VdbeListing    0x00000080  /* Debug listings of VDBE programs */
-#define SQLITE_WriteSchema    0x00000100  /* OK to update SQLITE_MASTER */
-#define SQLITE_VdbeAddopTrace 0x00000200  /* Trace sqlite3VdbeAddOp() calls */
-#define SQLITE_IgnoreChecks   0x00000400  /* Do not enforce check constraints */
-#define SQLITE_ReadUncommitted 0x0000800  /* For shared-cache mode */
-#define SQLITE_LegacyFileFmt  0x00001000  /* Create new databases in format 1 */
-#define SQLITE_FullFSync      0x00002000  /* Use full fsync on the backend */
-#define SQLITE_CkptFullFSync  0x00004000  /* Use full fsync for checkpoint */
-#define SQLITE_RecoveryMode   0x00008000  /* Ignore schema errors */
-#define SQLITE_ReverseOrder   0x00010000  /* Reverse unordered SELECTs */
-#define SQLITE_RecTriggers    0x00020000  /* Enable recursive triggers */
-#define SQLITE_ForeignKeys    0x00040000  /* Enforce foreign key constraints  */
-#define SQLITE_AutoIndex      0x00080000  /* Enable automatic indexes */
-#define SQLITE_PreferBuiltin  0x00100000  /* Preference to built-in funcs */
-#define SQLITE_LoadExtension  0x00200000  /* Enable load_extension */
-#define SQLITE_EnableTrigger  0x00400000  /* True to enable triggers */
+#define SQLITE_SqlTrace       0x00000200  /* Debug print SQL as it executes */
+#define SQLITE_VdbeListing    0x00000400  /* Debug listings of VDBE programs */
+#define SQLITE_WriteSchema    0x00000800  /* OK to update SQLITE_MASTER */
+#define SQLITE_VdbeAddopTrace 0x00001000  /* Trace sqlite3VdbeAddOp() calls */
+#define SQLITE_IgnoreChecks   0x00002000  /* Do not enforce check constraints */
+#define SQLITE_ReadUncommitted 0x0004000  /* For shared-cache mode */
+#define SQLITE_LegacyFileFmt  0x00008000  /* Create new databases in format 1 */
+#define SQLITE_RecoveryMode   0x00010000  /* Ignore schema errors */
+#define SQLITE_ReverseOrder   0x00020000  /* Reverse unordered SELECTs */
+#define SQLITE_RecTriggers    0x00040000  /* Enable recursive triggers */
+#define SQLITE_ForeignKeys    0x00080000  /* Enforce foreign key constraints  */
+#define SQLITE_AutoIndex      0x00100000  /* Enable automatic indexes */
+#define SQLITE_PreferBuiltin  0x00200000  /* Preference to built-in funcs */
+#define SQLITE_LoadExtension  0x00400000  /* Enable load_extension */
+#define SQLITE_EnableTrigger  0x00800000  /* True to enable triggers */
+#define SQLITE_DeferFKs       0x01000000  /* Defer all FK constraints */
+#define SQLITE_QueryOnly      0x02000000  /* Disable database changes */
+
 
 /*
 ** Bits of the sqlite3.dbOptFlags field that are used by the
@@ -10190,6 +10238,8 @@ struct sqlite3 {
 #define SQLITE_OrderByIdxJoin 0x0080   /* ORDER BY of joins via index */
 #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_AllOpts        0xffff   /* All optimizations */
 
 /*
@@ -10318,6 +10368,7 @@ struct FuncDestructor {
 struct Savepoint {
   char *zName;                        /* Savepoint name (nul-terminated) */
   i64 nDeferredCons;                  /* Number of deferred fk violations */
+  i64 nDeferredImmCons;               /* Number of deferred imm fk. */
   Savepoint *pNext;                   /* Parent savepoint (if any) */
 };
 
@@ -10636,12 +10687,16 @@ struct FKey {
 ** An instance of the following structure is passed as the first
 ** argument to sqlite3VdbeKeyCompare and is used to control the 
 ** comparison of the two index keys.
+**
+** Note that aSortOrder[] and aColl[] have nField+1 slots.  There
+** are nField slots for the columns of an index then one extra slot
+** for the rowid at the end.
 */
 struct KeyInfo {
   sqlite3 *db;        /* The database connection */
   u8 enc;             /* Text encoding - one of the SQLITE_UTF* values */
-  u16 nField;         /* Number of entries in aColl[] */
-  u8 *aSortOrder;     /* Sort order for each column.  May be NULL */
+  u16 nField;         /* Maximum index for aColl[] and aSortOrder[] */
+  u8 *aSortOrder;     /* Sort order for each column. */
   CollSeq *aColl[1];  /* Collating sequence for each term of the key */
 };
 
@@ -10710,11 +10765,13 @@ struct Index {
   Schema *pSchema;         /* Schema containing this 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 */
   int tnum;                /* DB Page containing root of this index */
   u16 nColumn;             /* Number of columns in table used by this index */
   u8 onError;              /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
   unsigned autoIndex:2;    /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
   unsigned bUnordered:1;   /* Use this index for == or IN queries only */
+  unsigned uniqNotNull:1;  /* True if UNIQUE and NOT NULL for all columns */
 #ifdef SQLITE_ENABLE_STAT3
   int nSample;             /* Number of elements in aSample[] */
   tRowcnt avgEq;           /* Average nEq value for key values not in aSample */
@@ -11061,6 +11118,11 @@ typedef u64 Bitmask;
 #define BMS  ((int)(sizeof(Bitmask)*8))
 
 /*
+** A bit in a Bitmask
+*/
+#define MASKBIT(n)   (((Bitmask)1)<<(n))
+
+/*
 ** The following structure describes the FROM clause of a SELECT statement.
 ** Each table or subquery in the FROM clause is a separate element of
 ** the SrcList.a[] array.
@@ -11080,8 +11142,8 @@ typedef u64 Bitmask;
 ** contains more than 63 columns and the 64-th or later column is used.
 */
 struct SrcList {
-  i16 nSrc;        /* Number of tables or subqueries in the FROM clause */
-  i16 nAlloc;      /* Number of entries allocated in a[] below */
+  u8 nSrc;        /* Number of tables or subqueries in the FROM clause */
+  u8 nAlloc;      /* Number of entries allocated in a[] below */
   struct SrcList_item {
     Schema *pSchema;  /* Schema to which this item is fixed */
     char *zDatabase;  /* Name of database holding this table */
@@ -11120,79 +11182,6 @@ struct SrcList {
 
 
 /*
-** A WherePlan object holds information that describes a lookup
-** strategy.
-**
-** This object is intended to be opaque outside of the where.c module.
-** It is included here only so that that compiler will know how big it
-** is.  None of the fields in this object should be used outside of
-** the where.c module.
-**
-** Within the union, pIdx is only used when wsFlags&WHERE_INDEXED is true.
-** pTerm is only used when wsFlags&WHERE_MULTI_OR is true.  And pVtabIdx
-** is only used when wsFlags&WHERE_VIRTUALTABLE is true.  It is never the
-** case that more than one of these conditions is true.
-*/
-struct WherePlan {
-  u32 wsFlags;                   /* WHERE_* flags that describe the strategy */
-  u16 nEq;                       /* Number of == constraints */
-  u16 nOBSat;                    /* Number of ORDER BY terms satisfied */
-  double nRow;                   /* Estimated number of rows (for EQP) */
-  union {
-    Index *pIdx;                   /* Index when WHERE_INDEXED is true */
-    struct WhereTerm *pTerm;       /* WHERE clause term for OR-search */
-    sqlite3_index_info *pVtabIdx;  /* Virtual table index to use */
-  } u;
-};
-
-/*
-** For each nested loop in a WHERE clause implementation, the WhereInfo
-** structure contains a single instance of this structure.  This structure
-** is intended to be private to the where.c module and should not be
-** access or modified by other modules.
-**
-** The pIdxInfo field is used to help pick the best index on a
-** virtual table.  The pIdxInfo pointer contains indexing
-** information for the i-th table in the FROM clause before reordering.
-** All the pIdxInfo pointers are freed by whereInfoFree() in where.c.
-** All other information in the i-th WhereLevel object for the i-th table
-** after FROM clause ordering.
-*/
-struct WhereLevel {
-  WherePlan plan;       /* query plan for this element of the FROM clause */
-  int iLeftJoin;        /* Memory cell used to implement LEFT OUTER JOIN */
-  int iTabCur;          /* The VDBE cursor used to access the table */
-  int iIdxCur;          /* The VDBE cursor used to access pIdx */
-  int addrBrk;          /* Jump here to break out of the loop */
-  int addrNxt;          /* Jump here to start the next IN combination */
-  int addrCont;         /* Jump here to continue with the next loop cycle */
-  int addrFirst;        /* First instruction of interior of the loop */
-  u8 iFrom;             /* Which entry in the FROM clause */
-  u8 op, p5;            /* Opcode and P5 of the opcode that ends the loop */
-  int p1, p2;           /* Operands of the opcode used to ends the loop */
-  union {               /* Information that depends on plan.wsFlags */
-    struct {
-      int nIn;              /* Number of entries in aInLoop[] */
-      struct InLoop {
-        int iCur;              /* The VDBE cursor used by this IN operator */
-        int addrInTop;         /* Top of the IN loop */
-        u8 eEndLoopOp;         /* IN Loop terminator. OP_Next or OP_Prev */
-      } *aInLoop;           /* Information about each nested IN operator */
-    } in;                 /* Used when plan.wsFlags&WHERE_IN_ABLE */
-    Index *pCovidx;       /* Possible covering index for WHERE_MULTI_OR */
-  } u;
-  double rOptCost;      /* "Optimal" cost for this level */
-
-  /* The following field is really not part of the current level.  But
-  ** we need a place to cache virtual table index information for each
-  ** virtual table in the FROM clause and the WhereLevel structure is
-  ** a convenient place since there is one WhereLevel for each FROM clause
-  ** element.
-  */
-  sqlite3_index_info *pIdxInfo;  /* Index info for n-th source table */
-};
-
-/*
 ** Flags appropriate for the wctrlFlags parameter of sqlite3WhereBegin()
 ** and the WhereInfo.wctrlFlags member.
 */
@@ -11205,33 +11194,12 @@ struct WhereLevel {
 #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_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 */
 
-/*
-** The WHERE clause processing routine has two halves.  The
-** first part does the start of the WHERE loop and the second
-** half does the tail of the WHERE loop.  An instance of
-** this structure is returned by the first half and passed
-** into the second half to give some continuity.
+/* Allowed return values from sqlite3WhereIsDistinct()
 */
-struct WhereInfo {
-  Parse *pParse;            /* Parsing and code generating context */
-  SrcList *pTabList;        /* List of tables in the join */
-  u16 nOBSat;               /* Number of ORDER BY terms satisfied by indices */
-  u16 wctrlFlags;           /* Flags originally passed to sqlite3WhereBegin() */
-  u8 okOnePass;             /* Ok to use one-pass algorithm for UPDATE/DELETE */
-  u8 untestedTerms;         /* Not all WHERE terms resolved by outer loop */
-  u8 eDistinct;             /* One of the WHERE_DISTINCT_* values below */
-  int iTop;                 /* The very beginning of the WHERE loop */
-  int iContinue;            /* Jump here to continue with next record */
-  int iBreak;               /* Jump here to break out of the loop */
-  int nLevel;               /* Number of nested loop */
-  struct WhereClause *pWC;  /* Decomposition of the WHERE clause */
-  double savedNQueryLoop;   /* pParse->nQueryLoop outside the WHERE loop */
-  double nRowOut;           /* Estimated number of output rows */
-  WhereLevel a[1];          /* Information about each nest loop in WHERE */
-};
-
-/* Allowed values for WhereInfo.eDistinct and DistinctCtx.eTnctType */
 #define WHERE_DISTINCT_NOOP      0  /* DISTINCT keyword not used */
 #define WHERE_DISTINCT_UNIQUE    1  /* No duplicates */
 #define WHERE_DISTINCT_ORDERED   2  /* All duplicates are adjacent */
@@ -11261,7 +11229,7 @@ struct WhereInfo {
 struct NameContext {
   Parse *pParse;       /* The parser */
   SrcList *pSrcList;   /* One or more tables used to resolve names */
-  ExprList *pEList;    /* Optional list of named expressions */
+  ExprList *pEList;    /* Optional list of result-set columns */
   AggInfo *pAggInfo;   /* Information about aggregates at this level */
   NameContext *pNext;  /* Next outer name context.  NULL for outermost */
   int nRef;            /* Number of names resolved by this context */
@@ -11276,8 +11244,7 @@ struct NameContext {
 #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_AsMaybe   0x10    /* Resolve to AS terms of the result set only
-                             ** if no other resolution is available */
+#define NC_PartIdx   0x10    /* True if resolving a partial index WHERE */
 
 /*
 ** An instance of the following structure contains all information
@@ -11305,7 +11272,7 @@ struct Select {
   u16 selFlags;          /* Various SF_* values */
   int iLimit, iOffset;   /* Memory registers holding LIMIT & OFFSET counters */
   int addrOpenEphm[3];   /* OP_OpenEphem opcodes related to this select */
-  double nSelectRow;     /* Estimated number of result rows */
+  u64 nSelectRow;        /* Estimated number of result rows */
   SrcList *pSrc;         /* The FROM clause */
   Expr *pWhere;          /* The WHERE clause */
   ExprList *pGroupBy;    /* The GROUP BY clause */
@@ -11332,6 +11299,7 @@ struct Select {
 #define SF_Values          0x0080  /* Synthesized from VALUES clause */
 #define SF_Materialize     0x0100  /* Force materialization of views */
 #define SF_NestedFrom      0x0200  /* Part of a parenthesized FROM clause */
+#define SF_MaybeConvert    0x0400  /* Need convertCompoundSelectToSubquery() */
 
 
 /*
@@ -11453,6 +11421,7 @@ struct Parse {
   u8 iColCache;        /* Next entry in aColCache[] to replace */
   u8 isMultiWrite;     /* True if statement may modify/insert multiple rows */
   u8 mayAbort;         /* True if statement may throw an ABORT exception */
+  u8 hasCompound;      /* Need to invoke convertCompoundSelectToSubquery() */
   int aTempReg[8];     /* Holding area for temporary registers */
   int nRangeReg;       /* Size of the temporary register block */
   int iRangeReg;       /* First register in temporary register block */
@@ -11462,6 +11431,7 @@ struct Parse {
   int nSet;            /* Number of sets used so far */
   int nOnce;           /* Number of OP_Once instructions so far */
   int ckBase;          /* Base register of data during check constraints */
+  int iPartIdxTab;     /* Table corresponding to a partial index */
   int iCacheLevel;     /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
   int iCacheCnt;       /* Counter used to generate aColCache[].lru values */
   struct yColCache {
@@ -11489,7 +11459,7 @@ struct Parse {
   /* Information used while coding trigger programs. */
   Parse *pToplevel;    /* Parse structure for main program (or NULL) */
   Table *pTriggerTab;  /* Table triggers are being coded for */
-  double nQueryLoop;   /* Estimated number of iterations of a query */
+  u32 nQueryLoop;      /* Est number of iterations of a query (10*log2(N)) */
   u32 oldmask;         /* Mask of old.* columns referenced */
   u32 newmask;         /* Mask of new.* columns referenced */
   u8 eTriggerOp;       /* TK_UPDATE, TK_INSERT or TK_DELETE */
@@ -11677,10 +11647,11 @@ struct StrAccum {
   int  nChar;          /* Length of the string so far */
   int  nAlloc;         /* Amount of space allocated in zText */
   int  mxAlloc;        /* Maximum allowed string length */
-  u8   mallocFailed;   /* Becomes true if any memory allocation fails */
   u8   useMalloc;      /* 0: none,  1: sqlite3DbMalloc,  2: sqlite3_malloc */
-  u8   tooBig;         /* Becomes true if string size exceeds limits */
+  u8   accError;       /* STRACCUM_NOMEM or STRACCUM_TOOBIG */
 };
+#define STRACCUM_NOMEM   1
+#define STRACCUM_TOOBIG  2
 
 /*
 ** A pointer to this structure is used to communicate information
@@ -12043,7 +12014,7 @@ SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*);
 SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*);
 SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*);
 SQLITE_PRIVATE Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
-                        Token*, int, int);
+                          Expr*, int, int);
 SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
 SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
 SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
@@ -12059,6 +12030,12 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
 SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
 SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
 SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
+SQLITE_PRIVATE u64 sqlite3WhereOutputRowCount(WhereInfo*);
+SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*);
+SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*);
+SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo*);
+SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo*);
+SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo*);
 SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
 SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
 SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int);
@@ -12085,8 +12062,9 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
 SQLITE_PRIVATE void sqlite3Vacuum(Parse*);
 SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*);
 SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*);
-SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*);
-SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*);
+SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*, int);
+SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*, int);
+SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Expr*, Expr*, int);
 SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
 SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
 SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
@@ -12113,7 +12091,7 @@ SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
 SQLITE_PRIVATE int sqlite3IsRowid(const char*);
 SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int);
 SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int*);
-SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int);
+SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*);
 SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int,
                                      int*,int,int,int,int,int*);
 SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
@@ -12316,6 +12294,7 @@ SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
 SQLITE_PRIVATE int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
 SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
 SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
+SQLITE_PRIVATE void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
 SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
 SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
 SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
@@ -12335,6 +12314,7 @@ SQLITE_PRIVATE void sqlite3MinimumFileFormat(Parse*, int, int);
 SQLITE_PRIVATE void sqlite3SchemaClear(void *);
 SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
 SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int);
 SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *);
 SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, 
   void (*)(sqlite3_context*,int,sqlite3_value **),
@@ -12396,13 +12376,14 @@ SQLITE_PRIVATE   int sqlite3Utf8To8(unsigned char*);
 #else
 SQLITE_PRIVATE    void sqlite3VtabClear(sqlite3 *db, Table*);
 SQLITE_PRIVATE    void sqlite3VtabDisconnect(sqlite3 *db, Table *p);
-SQLITE_PRIVATE    int sqlite3VtabSync(sqlite3 *db, char **);
+SQLITE_PRIVATE    int sqlite3VtabSync(sqlite3 *db, Vdbe*);
 SQLITE_PRIVATE    int sqlite3VtabRollback(sqlite3 *db);
 SQLITE_PRIVATE    int sqlite3VtabCommit(sqlite3 *db);
 SQLITE_PRIVATE    void sqlite3VtabLock(VTable *);
 SQLITE_PRIVATE    void sqlite3VtabUnlock(VTable *);
 SQLITE_PRIVATE    void sqlite3VtabUnlockList(sqlite3*);
 SQLITE_PRIVATE    int sqlite3VtabSavepoint(sqlite3 *, int, int);
+SQLITE_PRIVATE    void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*);
 SQLITE_PRIVATE    VTable *sqlite3GetVTable(sqlite3*, Table*);
 #  define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
 #endif
@@ -13287,6 +13268,9 @@ 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
@@ -13473,23 +13457,19 @@ struct Mem {
 #define memIsValid(M)  ((M)->flags & MEM_Invalid)==0
 #endif
 
-
-/* A VdbeFunc is just a FuncDef (defined in sqliteInt.h) that contains
-** additional information about auxiliary information bound to arguments
-** of the function.  This is used to implement the sqlite3_get_auxdata()
-** and sqlite3_set_auxdata() APIs.  The "auxdata" is some auxiliary data
-** that can be associated with a constant argument to a function.  This
-** allows functions such as "regexp" to compile their constant regular
-** expression argument once and reused the compiled code for multiple
-** invocations.
+/*
+** Each auxilliary 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 VdbeFunc {
-  FuncDef *pFunc;               /* The definition of the function */
-  int nAux;                     /* Number of entries allocated for apAux[] */
-  struct AuxData {
-    void *pAux;                   /* Aux data for the i-th argument */
-    void (*xDelete)(void *);      /* Destructor for the aux data */
-  } apAux[1];                   /* One slot for each function argument */
+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 */
 };
 
 /*
@@ -13507,12 +13487,14 @@ struct VdbeFunc {
 */
 struct sqlite3_context {
   FuncDef *pFunc;       /* Pointer to function information.  MUST BE FIRST */
-  VdbeFunc *pVdbeFunc;  /* Auxilary data, if created. */
   Mem s;                /* The return value is stored here */
   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. */
-  int skipFlag;         /* Skip skip accumulator loading if true */
+  u8 skipFlag;          /* Skip skip accumulator loading if true */
+  u8 fErrorOrAux;       /* isError!=0 or pVdbe->pAuxData modified */
 };
 
 /*
@@ -13580,19 +13562,21 @@ struct Vdbe {
   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 read-only statements */
+  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) */
-  int aCounter[3];        /* Counters used by sqlite3_stmt_status() */
+  u32 aCounter[5];        /* Counters used by sqlite3_stmt_status() */
 #ifndef SQLITE_OMIT_TRACE
   i64 startTime;          /* Time when query started - used for profiling */
 #endif
   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 */
 #ifdef SQLITE_DEBUG
@@ -13609,6 +13593,7 @@ struct Vdbe {
   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 */
 };
 
 /*
@@ -13632,7 +13617,7 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
 SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int);
 SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int);
 SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
-SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);
+SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe*, int, int);
 
 int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
 SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*);
@@ -13953,6 +13938,16 @@ SQLITE_API int sqlite3_db_status(
       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;
+      *pCurrent = db->nDeferredImmCons>0 || db->nDeferredCons>0;
+      break;
+    }
+
     default: {
       rc = SQLITE_ERROR;
     }
@@ -17252,13 +17247,13 @@ static SQLITE_WSD struct Mem5Global {
 } mem5;
 
 /*
-** Access the static variable through a macro for SQLITE_OMIT_WSD
+** Access the static variable through a macro for SQLITE_OMIT_WSD.
 */
 #define mem5 GLOBAL(struct Mem5Global, mem5)
 
 /*
 ** Assuming mem5.zPool is divided up into an array of Mem5Link
-** structures, return a pointer to the idx-th such lik.
+** structures, return a pointer to the idx-th such link.
 */
 #define MEM5LINK(idx) ((Mem5Link *)(&mem5.zPool[(idx)*mem5.szAtom]))
 
@@ -17354,7 +17349,7 @@ static int memsys5UnlinkFirst(int iLogsize){
 ** Return a block of memory of at least nBytes in size.
 ** Return NULL if unable.  Return NULL if nBytes==0.
 **
-** The caller guarantees that nByte positive.
+** The caller guarantees that nByte is positive.
 **
 ** The caller has obtained a mutex prior to invoking this
 ** routine so there is never any chance that two or more
@@ -17476,7 +17471,7 @@ static void memsys5FreeUnsafe(void *pOld){
 }
 
 /*
-** Allocate nBytes of memory
+** Allocate nBytes of memory.
 */
 static void *memsys5Malloc(int nBytes){
   sqlite3_int64 *p = 0;
@@ -19908,7 +19903,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
           nOut = precision + 10;
           zOut = zExtra = sqlite3Malloc( nOut );
           if( zOut==0 ){
-            pAccum->mallocFailed = 1;
+            pAccum->accError = STRACCUM_NOMEM;
             return;
           }
         }
@@ -19962,13 +19957,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
           else                         prefix = 0;
         }
         if( xtype==etGENERIC && precision>0 ) precision--;
-#if 0
-        /* Rounding works like BSD when the constant 0.4999 is used.  Wierd! */
-        for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1);
-#else
-        /* It makes more sense to use 0.5 */
         for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1){}
-#endif
         if( xtype==etFLOAT ) realvalue += rounder;
         /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
         exp = 0;
@@ -20023,10 +20012,10 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
         }else{
           e2 = exp;
         }
-        if( e2+precision+width > etBUFSIZE - 15 ){
-          bufpt = zExtra = sqlite3Malloc( e2+precision+width+15 );
+        if( MAX(e2,0)+precision+width > etBUFSIZE - 15 ){
+          bufpt = zExtra = sqlite3Malloc( MAX(e2,0)+precision+width+15 );
           if( bufpt==0 ){
-            pAccum->mallocFailed = 1;
+            pAccum->accError = STRACCUM_NOMEM;
             return;
           }
         }
@@ -20161,7 +20150,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
         if( n>etBUFSIZE ){
           bufpt = zExtra = sqlite3Malloc( n );
           if( bufpt==0 ){
-            pAccum->mallocFailed = 1;
+            pAccum->accError = STRACCUM_NOMEM;
             return;
           }
         }else{
@@ -20239,22 +20228,20 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
 */
 SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
   assert( z!=0 || N==0 );
-  if( p->tooBig | p->mallocFailed ){
-    testcase(p->tooBig);
-    testcase(p->mallocFailed);
+  if( p->accError ){
+    testcase(p->accError==STRACCUM_TOOBIG);
+    testcase(p->accError==STRACCUM_NOMEM);
     return;
   }
   assert( p->zText!=0 || p->nChar==0 );
-  if( N<0 ){
+  if( N<=0 ){
+    if( N==0 || z[0]==0 ) return;
     N = sqlite3Strlen30(z);
   }
-  if( N==0 || NEVER(z==0) ){
-    return;
-  }
   if( p->nChar+N >= p->nAlloc ){
     char *zNew;
     if( !p->useMalloc ){
-      p->tooBig = 1;
+      p->accError = STRACCUM_TOOBIG;
       N = p->nAlloc - p->nChar - 1;
       if( N<=0 ){
         return;
@@ -20265,7 +20252,7 @@ SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
       szNew += N + 1;
       if( szNew > p->mxAlloc ){
         sqlite3StrAccumReset(p);
-        p->tooBig = 1;
+        p->accError = STRACCUM_TOOBIG;
         return;
       }else{
         p->nAlloc = (int)szNew;
@@ -20279,7 +20266,7 @@ SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
         if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
         p->zText = zNew;
       }else{
-        p->mallocFailed = 1;
+        p->accError = STRACCUM_NOMEM;
         sqlite3StrAccumReset(p);
         return;
       }
@@ -20307,7 +20294,7 @@ SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){
       if( p->zText ){
         memcpy(p->zText, p->zBase, p->nChar+1);
       }else{
-        p->mallocFailed = 1;
+        p->accError = STRACCUM_NOMEM;
       }
     }
   }
@@ -20338,8 +20325,7 @@ SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n, int mx)
   p->nAlloc = n;
   p->mxAlloc = mx;
   p->useMalloc = 1;
-  p->tooBig = 0;
-  p->mallocFailed = 0;
+  p->accError = 0;
 }
 
 /*
@@ -20356,7 +20342,7 @@ SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list a
   acc.db = db;
   sqlite3VXPrintf(&acc, 1, zFormat, ap);
   z = sqlite3StrAccumFinish(&acc);
-  if( acc.mallocFailed ){
+  if( acc.accError==STRACCUM_NOMEM ){
     db->mallocFailed = 1;
   }
   return z;
@@ -20553,24 +20539,11 @@ static SQLITE_WSD struct sqlite3PrngType {
 } sqlite3Prng;
 
 /*
-** Get a single 8-bit random value from the RC4 PRNG.  The Mutex
-** must be held while executing this routine.
-**
-** Why not just use a library random generator like lrand48() for this?
-** Because the OP_NewRowid opcode in the VDBE depends on having a very
-** good source of random numbers.  The lrand48() library function may
-** well be good enough.  But maybe not.  Or maybe lrand48() has some
-** subtle problems on some systems that could cause problems.  It is hard
-** to know.  To minimize the risk of problems due to bad lrand48()
-** implementations, SQLite uses this random number generator based
-** on RC4, which we know works very well.
-**
-** (Later):  Actually, OP_NewRowid does not depend on a good source of
-** randomness any more.  But we will leave this code in all the same.
+** Return N random bytes.
 */
-static u8 randomByte(void){
+SQLITE_API void sqlite3_randomness(int N, void *pBuf){
   unsigned char t;
-
+  unsigned char *zBuf = pBuf;
 
   /* The "wsdPrng" macro will resolve to the pseudo-random number generator
   ** state vector.  If writable static data is unsupported on the target,
@@ -20585,6 +20558,10 @@ static u8 randomByte(void){
 # define wsdPrng sqlite3Prng
 #endif
 
+#if SQLITE_THREADSAFE
+  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
+  sqlite3_mutex_enter(mutex);
+#endif
 
   /* Initialize the state of the random number generator once,
   ** the first time this routine is called.  The seed value does
@@ -20613,28 +20590,14 @@ static u8 randomByte(void){
     wsdPrng.isInit = 1;
   }
 
-  /* Generate and return single random byte
-  */
-  wsdPrng.i++;
-  t = wsdPrng.s[wsdPrng.i];
-  wsdPrng.j += t;
-  wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j];
-  wsdPrng.s[wsdPrng.j] = t;
-  t += wsdPrng.s[wsdPrng.i];
-  return wsdPrng.s[t];
-}
-
-/*
-** Return N random bytes.
-*/
-SQLITE_API void sqlite3_randomness(int N, void *pBuf){
-  unsigned char *zBuf = pBuf;
-#if SQLITE_THREADSAFE
-  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
-#endif
-  sqlite3_mutex_enter(mutex);
   while( N-- ){
-    *(zBuf++) = randomByte();
+    wsdPrng.i++;
+    t = wsdPrng.s[wsdPrng.i];
+    wsdPrng.j += t;
+    wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j];
+    wsdPrng.s[wsdPrng.j] = t;
+    t += wsdPrng.s[wsdPrng.i];
+    *(zBuf++) = wsdPrng.s[t];
   }
   sqlite3_mutex_leave(mutex);
 }
@@ -22727,78 +22690,78 @@ SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, int nKey, voi
 #if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
 SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
  static const char *const azName[] = { "?",
-     /*   1 */ "Goto",
-     /*   2 */ "Gosub",
-     /*   3 */ "Return",
-     /*   4 */ "Yield",
-     /*   5 */ "HaltIfNull",
-     /*   6 */ "Halt",
-     /*   7 */ "Integer",
-     /*   8 */ "Int64",
-     /*   9 */ "String",
-     /*  10 */ "Null",
-     /*  11 */ "Blob",
-     /*  12 */ "Variable",
-     /*  13 */ "Move",
-     /*  14 */ "Copy",
-     /*  15 */ "SCopy",
-     /*  16 */ "ResultRow",
-     /*  17 */ "CollSeq",
-     /*  18 */ "Function",
+     /*   1 */ "Function",
+     /*   2 */ "Savepoint",
+     /*   3 */ "AutoCommit",
+     /*   4 */ "Transaction",
+     /*   5 */ "SorterNext",
+     /*   6 */ "Prev",
+     /*   7 */ "Next",
+     /*   8 */ "AggStep",
+     /*   9 */ "Checkpoint",
+     /*  10 */ "JournalMode",
+     /*  11 */ "Vacuum",
+     /*  12 */ "VFilter",
+     /*  13 */ "VUpdate",
+     /*  14 */ "Goto",
+     /*  15 */ "Gosub",
+     /*  16 */ "Return",
+     /*  17 */ "Yield",
+     /*  18 */ "HaltIfNull",
      /*  19 */ "Not",
-     /*  20 */ "AddImm",
-     /*  21 */ "MustBeInt",
-     /*  22 */ "RealAffinity",
-     /*  23 */ "Permutation",
-     /*  24 */ "Compare",
-     /*  25 */ "Jump",
-     /*  26 */ "Once",
-     /*  27 */ "If",
-     /*  28 */ "IfNot",
-     /*  29 */ "Column",
-     /*  30 */ "Affinity",
-     /*  31 */ "MakeRecord",
-     /*  32 */ "Count",
-     /*  33 */ "Savepoint",
-     /*  34 */ "AutoCommit",
-     /*  35 */ "Transaction",
-     /*  36 */ "ReadCookie",
-     /*  37 */ "SetCookie",
-     /*  38 */ "VerifyCookie",
-     /*  39 */ "OpenRead",
-     /*  40 */ "OpenWrite",
-     /*  41 */ "OpenAutoindex",
-     /*  42 */ "OpenEphemeral",
-     /*  43 */ "SorterOpen",
-     /*  44 */ "OpenPseudo",
-     /*  45 */ "Close",
-     /*  46 */ "SeekLt",
-     /*  47 */ "SeekLe",
-     /*  48 */ "SeekGe",
-     /*  49 */ "SeekGt",
-     /*  50 */ "Seek",
-     /*  51 */ "NotFound",
-     /*  52 */ "Found",
-     /*  53 */ "IsUnique",
-     /*  54 */ "NotExists",
-     /*  55 */ "Sequence",
-     /*  56 */ "NewRowid",
-     /*  57 */ "Insert",
-     /*  58 */ "InsertInt",
-     /*  59 */ "Delete",
-     /*  60 */ "ResetCount",
-     /*  61 */ "SorterCompare",
-     /*  62 */ "SorterData",
-     /*  63 */ "RowKey",
-     /*  64 */ "RowData",
-     /*  65 */ "Rowid",
-     /*  66 */ "NullRow",
-     /*  67 */ "Last",
+     /*  20 */ "Halt",
+     /*  21 */ "Integer",
+     /*  22 */ "Int64",
+     /*  23 */ "String",
+     /*  24 */ "Null",
+     /*  25 */ "Blob",
+     /*  26 */ "Variable",
+     /*  27 */ "Move",
+     /*  28 */ "Copy",
+     /*  29 */ "SCopy",
+     /*  30 */ "ResultRow",
+     /*  31 */ "CollSeq",
+     /*  32 */ "AddImm",
+     /*  33 */ "MustBeInt",
+     /*  34 */ "RealAffinity",
+     /*  35 */ "Permutation",
+     /*  36 */ "Compare",
+     /*  37 */ "Jump",
+     /*  38 */ "Once",
+     /*  39 */ "If",
+     /*  40 */ "IfNot",
+     /*  41 */ "Column",
+     /*  42 */ "Affinity",
+     /*  43 */ "MakeRecord",
+     /*  44 */ "Count",
+     /*  45 */ "ReadCookie",
+     /*  46 */ "SetCookie",
+     /*  47 */ "VerifyCookie",
+     /*  48 */ "OpenRead",
+     /*  49 */ "OpenWrite",
+     /*  50 */ "OpenAutoindex",
+     /*  51 */ "OpenEphemeral",
+     /*  52 */ "SorterOpen",
+     /*  53 */ "OpenPseudo",
+     /*  54 */ "Close",
+     /*  55 */ "SeekLt",
+     /*  56 */ "SeekLe",
+     /*  57 */ "SeekGe",
+     /*  58 */ "SeekGt",
+     /*  59 */ "Seek",
+     /*  60 */ "NotFound",
+     /*  61 */ "Found",
+     /*  62 */ "IsUnique",
+     /*  63 */ "NotExists",
+     /*  64 */ "Sequence",
+     /*  65 */ "NewRowid",
+     /*  66 */ "Insert",
+     /*  67 */ "InsertInt",
      /*  68 */ "Or",
      /*  69 */ "And",
-     /*  70 */ "SorterSort",
-     /*  71 */ "Sort",
-     /*  72 */ "Rewind",
+     /*  70 */ "Delete",
+     /*  71 */ "ResetCount",
+     /*  72 */ "SorterCompare",
      /*  73 */ "IsNull",
      /*  74 */ "NotNull",
      /*  75 */ "Ne",
@@ -22807,7 +22770,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
      /*  78 */ "Le",
      /*  79 */ "Lt",
      /*  80 */ "Ge",
-     /*  81 */ "SorterNext",
+     /*  81 */ "SorterData",
      /*  82 */ "BitAnd",
      /*  83 */ "BitOr",
      /*  84 */ "ShiftLeft",
@@ -22818,55 +22781,55 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
      /*  89 */ "Divide",
      /*  90 */ "Remainder",
      /*  91 */ "Concat",
-     /*  92 */ "Prev",
+     /*  92 */ "RowKey",
      /*  93 */ "BitNot",
      /*  94 */ "String8",
-     /*  95 */ "Next",
-     /*  96 */ "SorterInsert",
-     /*  97 */ "IdxInsert",
-     /*  98 */ "IdxDelete",
-     /*  99 */ "IdxRowid",
-     /* 100 */ "IdxLT",
-     /* 101 */ "IdxGE",
-     /* 102 */ "Destroy",
-     /* 103 */ "Clear",
-     /* 104 */ "CreateIndex",
-     /* 105 */ "CreateTable",
-     /* 106 */ "ParseSchema",
-     /* 107 */ "LoadAnalysis",
-     /* 108 */ "DropTable",
-     /* 109 */ "DropIndex",
-     /* 110 */ "DropTrigger",
-     /* 111 */ "IntegrityCk",
-     /* 112 */ "RowSetAdd",
-     /* 113 */ "RowSetRead",
-     /* 114 */ "RowSetTest",
-     /* 115 */ "Program",
-     /* 116 */ "Param",
-     /* 117 */ "FkCounter",
-     /* 118 */ "FkIfZero",
-     /* 119 */ "MemMax",
-     /* 120 */ "IfPos",
-     /* 121 */ "IfNeg",
-     /* 122 */ "IfZero",
-     /* 123 */ "AggStep",
-     /* 124 */ "AggFinal",
-     /* 125 */ "Checkpoint",
-     /* 126 */ "JournalMode",
-     /* 127 */ "Vacuum",
-     /* 128 */ "IncrVacuum",
-     /* 129 */ "Expire",
+     /*  95 */ "RowData",
+     /*  96 */ "Rowid",
+     /*  97 */ "NullRow",
+     /*  98 */ "Last",
+     /*  99 */ "SorterSort",
+     /* 100 */ "Sort",
+     /* 101 */ "Rewind",
+     /* 102 */ "SorterInsert",
+     /* 103 */ "IdxInsert",
+     /* 104 */ "IdxDelete",
+     /* 105 */ "IdxRowid",
+     /* 106 */ "IdxLT",
+     /* 107 */ "IdxGE",
+     /* 108 */ "Destroy",
+     /* 109 */ "Clear",
+     /* 110 */ "CreateIndex",
+     /* 111 */ "CreateTable",
+     /* 112 */ "ParseSchema",
+     /* 113 */ "LoadAnalysis",
+     /* 114 */ "DropTable",
+     /* 115 */ "DropIndex",
+     /* 116 */ "DropTrigger",
+     /* 117 */ "IntegrityCk",
+     /* 118 */ "RowSetAdd",
+     /* 119 */ "RowSetRead",
+     /* 120 */ "RowSetTest",
+     /* 121 */ "Program",
+     /* 122 */ "Param",
+     /* 123 */ "FkCounter",
+     /* 124 */ "FkIfZero",
+     /* 125 */ "MemMax",
+     /* 126 */ "IfPos",
+     /* 127 */ "IfNeg",
+     /* 128 */ "IfZero",
+     /* 129 */ "AggFinal",
      /* 130 */ "Real",
-     /* 131 */ "TableLock",
-     /* 132 */ "VBegin",
-     /* 133 */ "VCreate",
-     /* 134 */ "VDestroy",
-     /* 135 */ "VOpen",
-     /* 136 */ "VFilter",
-     /* 137 */ "VColumn",
-     /* 138 */ "VNext",
-     /* 139 */ "VRename",
-     /* 140 */ "VUpdate",
+     /* 131 */ "IncrVacuum",
+     /* 132 */ "Expire",
+     /* 133 */ "TableLock",
+     /* 134 */ "VBegin",
+     /* 135 */ "VCreate",
+     /* 136 */ "VDestroy",
+     /* 137 */ "VOpen",
+     /* 138 */ "VColumn",
+     /* 139 */ "VNext",
+     /* 140 */ "VRename",
      /* 141 */ "ToText",
      /* 142 */ "ToBlob",
      /* 143 */ "ToNumeric",
@@ -22931,13 +22894,6 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
 */
 #if SQLITE_OS_UNIX              /* This file is used on unix only */
 
-/* Use posix_fallocate() if it is available
-*/
-#if !defined(HAVE_POSIX_FALLOCATE) \
-      && (_XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L)
-# define HAVE_POSIX_FALLOCATE 1
-#endif
-
 /*
 ** There are various methods for file locking used for concurrency
 ** control:
@@ -26868,15 +26824,19 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
     }
     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 ){
+      if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
         pFile->mmapSizeMax = newLimit;
-        if( newLimit<pFile->mmapSize ) pFile->mmapSize = newLimit;
+        if( pFile->mmapSize>0 ){
+          unixUnmapfile(pFile);
+          rc = unixMapfile(pFile, -1);
+        }
       }
-      return SQLITE_OK;
+      return rc;
     }
 #ifdef SQLITE_DEBUG
     /* The pager calls this method to signal that it has done
@@ -30526,6 +30486,7 @@ SQLITE_API int sqlite3_os_end(void){
 
 #ifdef __CYGWIN__
 # include <sys/cygwin.h>
+/* # include <errno.h> */
 #endif
 
 /*
@@ -30802,13 +30763,6 @@ WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID);
 #endif /* SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL) */
 
 /*
-** Macro to find the minimum of two numeric values.
-*/
-#ifndef MIN
-# define MIN(x,y) ((x)<(y)?(x):(y))
-#endif
-
-/*
 ** Some Microsoft compilers lack this definition.
 */
 #ifndef INVALID_FILE_ATTRIBUTES
@@ -30954,6 +30908,7 @@ struct winFile {
 #  define SQLITE_WIN32_HEAP_FLAGS     (0)
 #endif
 
+
 /*
 ** The winMemData structure stores information required by the Win32-specific
 ** sqlite3_mem_methods implementation.
@@ -33533,6 +33488,9 @@ static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){
 
 /* Forward declaration */
 static int getTempname(int nBuf, char *zBuf);
+#if SQLITE_MAX_MMAP_SIZE>0
+static int winMapfile(winFile*, sqlite3_int64);
+#endif
 
 /*
 ** Control and query of the open file handle.
@@ -33616,13 +33574,20 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
 #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 ) pFile->mmapSizeMax = newLimit;
-      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
-      return SQLITE_OK;
+      if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
+        pFile->mmapSizeMax = newLimit;
+        if( pFile->mmapSize>0 ){
+          (void)winUnmapfile(pFile);
+          rc = winMapfile(pFile, -1);
+        }
+      }
+      OSTRACE(("FCNTL file=%p, rc=%d\n", pFile->h, rc));
+      return rc;
     }
 #endif
   }
@@ -34408,10 +34373,10 @@ static int winMapfile(winFile *pFd, sqlite3_int64 nByte){
       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, nMap);
+    pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, (SIZE_T)nMap);
 #else
-    assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff );
     pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap);
 #endif
     if( pNew==NULL ){
@@ -34581,6 +34546,15 @@ static void *convertUtf8Filename(const char *zFilename){
 }
 
 /*
+** Maximum pathname length (in bytes) for windows.  The MAX_PATH macro is
+** in characters, so we allocate 3 bytes per character assuming worst-case
+** 3-bytes-per-character UTF8.
+*/
+#ifndef SQLITE_WIN32_MAX_PATH
+#  define SQLITE_WIN32_MAX_PATH   (MAX_PATH*3)
+#endif
+
+/*
 ** Create a temporary file name in zBuf.  zBuf must be big enough to
 ** hold at pVfs->mxPathname characters.
 */
@@ -34591,7 +34565,7 @@ static int getTempname(int nBuf, char *zBuf){
     "0123456789";
   size_t i, j;
   int nTempPath;
-  char zTempPath[MAX_PATH+2];
+  char zTempPath[SQLITE_WIN32_MAX_PATH+2];
 
   /* 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
@@ -34599,19 +34573,21 @@ static int getTempname(int nBuf, char *zBuf){
   */
   SimulateIOError( return SQLITE_IOERR );
 
-  memset(zTempPath, 0, MAX_PATH+2);
-
   if( sqlite3_temp_directory ){
-    sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
+    sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s",
+                     sqlite3_temp_directory);
   }
 #if !SQLITE_OS_WINRT
   else if( isNT() ){
     char *zMulti;
     WCHAR zWidePath[MAX_PATH];
-    osGetTempPathW(MAX_PATH-30, zWidePath);
+    if( osGetTempPathW(MAX_PATH-30, zWidePath)==0 ){
+      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
+      return SQLITE_IOERR_GETTEMPPATH;
+    }
     zMulti = unicodeToUtf8(zWidePath);
     if( zMulti ){
-      sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti);
+      sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", zMulti);
       sqlite3_free(zMulti);
     }else{
       OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
@@ -34621,19 +34597,38 @@ static int getTempname(int nBuf, char *zBuf){
 #ifdef SQLITE_WIN32_HAS_ANSI
   else{
     char *zUtf8;
-    char zMbcsPath[MAX_PATH];
-    osGetTempPathA(MAX_PATH-30, zMbcsPath);
+    char zMbcsPath[SQLITE_WIN32_MAX_PATH];
+    if( osGetTempPathA(SQLITE_WIN32_MAX_PATH-30, zMbcsPath)==0 ){
+      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
+      return SQLITE_IOERR_GETTEMPPATH;
+    }
     zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
     if( zUtf8 ){
-      sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
+      sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", zUtf8);
       sqlite3_free(zUtf8);
     }else{
       OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
       return SQLITE_IOERR_NOMEM;
     }
   }
-#endif
-#endif
+#else
+  else{
+    /*
+    ** Compiled without ANSI support and the current operating system
+    ** is not Windows NT; therefore, just zero the temporary buffer.
+    */
+    memset(zTempPath, 0, SQLITE_WIN32_MAX_PATH+2);
+  }
+#endif /* SQLITE_WIN32_HAS_ANSI */
+#else
+  else{
+    /*
+    ** Compiled for WinRT and the sqlite3_temp_directory is not set;
+    ** therefore, just zero the temporary buffer.
+    */
+    memset(zTempPath, 0, SQLITE_WIN32_MAX_PATH+2);
+  }
+#endif /* !SQLITE_OS_WINRT */
 
   /* Check that the output buffer is large enough for the temporary file 
   ** name. If it is not, return SQLITE_ERROR.
@@ -34719,7 +34714,7 @@ static int winOpen(
   /* 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[MAX_PATH+2];     /* Buffer used to create temp filename */
+  char zTmpname[SQLITE_WIN32_MAX_PATH+2];     /* Buffer used to create temp filename */
 
   int rc = SQLITE_OK;            /* Function Return Code */
 #if !defined(NDEBUG) || SQLITE_OS_WINCE
@@ -34785,8 +34780,7 @@ static int winOpen(
   */
   if( !zUtf8Name ){
     assert(isDelete && !isOpenJournal);
-    memset(zTmpname, 0, MAX_PATH+2);
-    rc = getTempname(MAX_PATH+2, zTmpname);
+    rc = getTempname(SQLITE_WIN32_MAX_PATH+2, zTmpname);
     if( rc!=SQLITE_OK ){
       OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc)));
       return rc;
@@ -35217,7 +35211,7 @@ static int winFullPathname(
 #if defined(__CYGWIN__)
   SimulateIOError( return SQLITE_ERROR );
   UNUSED_PARAMETER(nFull);
-  assert( pVfs->mxPathname>=MAX_PATH );
+  assert( pVfs->mxPathname>=SQLITE_WIN32_MAX_PATH );
   assert( nFull>=pVfs->mxPathname );
   if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
     /*
@@ -35226,14 +35220,21 @@ static int winFullPathname(
     **       for converting the relative path name to an absolute
     **       one by prepending the data directory and a slash.
     */
-    char zOut[MAX_PATH+1];
-    memset(zOut, 0, MAX_PATH+1);
-    cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut,
-                     MAX_PATH+1);
+    char zOut[SQLITE_WIN32_MAX_PATH+1];
+    if( cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut,
+                         SQLITE_WIN32_MAX_PATH+1)<0 ){
+      winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path",
+                  zRelative);
+      return SQLITE_CANTOPEN_FULLPATH;
+    }
     sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
                      sqlite3_data_directory, zOut);
   }else{
-    cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull);
+    if( cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull)<0 ){
+      winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path",
+                  zRelative);
+      return SQLITE_CANTOPEN_FULLPATH;
+    }
   }
   return SQLITE_OK;
 #endif
@@ -35575,7 +35576,7 @@ SQLITE_API int sqlite3_os_init(void){
   static sqlite3_vfs winVfs = {
     3,                   /* iVersion */
     sizeof(winFile),     /* szOsFile */
-    MAX_PATH,            /* mxPathname */
+    SQLITE_WIN32_MAX_PATH, /* mxPathname */
     0,                   /* pNext */
     "win32",             /* zName */
     0,                   /* pAppData */
@@ -37222,7 +37223,7 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
   int sz;               /* Bytes of memory required to allocate the new cache */
 
   /*
-  ** The seperateCache variable is true if each PCache has its own private
+  ** 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.
   **
@@ -37425,6 +37426,7 @@ static sqlite3_pcache_page *pcache1Fetch(
   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 && (
@@ -38786,6 +38788,13 @@ struct PagerSavepoint {
 };
 
 /*
+** Bits of the Pager.doNotSpill flag.  See further description below.
+*/
+#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 */
+
+/*
 ** A open page cache is an instance of struct Pager. A description of
 ** some of the more important member variables follows:
 **
@@ -38851,19 +38860,21 @@ struct PagerSavepoint {
 **   journal file from being successfully finalized, the setMaster flag
 **   is cleared anyway (and the pager will move to ERROR state).
 **
-** doNotSpill, doNotSyncSpill
+** doNotSpill
 **
-**   These two boolean 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).
+**   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 doNotSpill is non-zero, writing to the database from pagerStress()
-**   is disabled altogether. This is done in a very obscure case that
+**   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().
+**   while it is being traversed by code in pager_playback().  The SPILLFLAG_OFF
+**   case is a user preference.
 ** 
-**   If doNotSyncSpill is non-zero, writing to the database from pagerStress()
+**   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 
@@ -38967,7 +38978,6 @@ struct Pager {
   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 doNotSyncSpill;          /* Do not do a spill that requires jrnl sync */
   u8 subjInMemory;            /* True to use in-memory sub-journals */
   Pgno dbSize;                /* Number of pages in the database */
   Pgno dbOrigSize;            /* dbSize before the current transaction */
@@ -39346,13 +39356,17 @@ static char *print_pager_state(Pager *p){
 **     PagerSavepoint.pInSavepoint.
 */
 static int subjRequiresPage(PgHdr *pPg){
-  Pgno pgno = pPg->pgno;
   Pager *pPager = pPg->pPager;
+  PagerSavepoint *p;
+  Pgno pgno;
   int i;
-  for(i=0; i<pPager->nSavepoint; i++){
-    PagerSavepoint *p = &pPager->aSavepoint[i];
-    if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){
-      return 1;
+  if( pPager->nSavepoint ){
+    pgno = pPg->pgno;
+    for(i=0; i<pPager->nSavepoint; i++){
+      p = &pPager->aSavepoint[i];
+      if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){
+        return 1;
+      }
     }
   }
   return 0;
@@ -40144,6 +40158,7 @@ static void pager_unlock(Pager *pPager){
     pPager->changeCountDone = pPager->tempFile;
     pPager->eState = PAGER_OPEN;
     pPager->errCode = SQLITE_OK;
+    if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
   }
 
   pPager->journalOff = 0;
@@ -40626,11 +40641,11 @@ static int pager_playback_one_page(
     ** requiring a journal-sync before it is written.
     */
     assert( isSavepnt );
-    assert( pPager->doNotSpill==0 );
-    pPager->doNotSpill++;
+    assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)==0 );
+    pPager->doNotSpill |= SPILLFLAG_ROLLBACK;
     rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1);
-    assert( pPager->doNotSpill==1 );
-    pPager->doNotSpill--;
+    assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 );
+    pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK;
     if( rc!=SQLITE_OK ) return rc;
     pPg->flags &= ~PGHDR_NEED_READ;
     sqlite3PcacheMakeDirty(pPg);
@@ -41197,12 +41212,6 @@ static int readDbPage(PgHdr *pPg, u32 iFrame){
   assert( pPager->eState>=PAGER_READER && !MEMDB );
   assert( isOpen(pPager->fd) );
 
-  if( NEVER(!isOpen(pPager->fd)) ){
-    assert( pPager->tempFile );
-    memset(pPg->pData, 0, pPager->pageSize);
-    return SQLITE_OK;
-  }
-
 #ifndef SQLITE_OMIT_WAL
   if( iFrame ){
     /* Try to pull the page from the write-ahead log. */
@@ -41710,10 +41719,10 @@ SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){
 static void pagerFixMaplimit(Pager *pPager){
 #if SQLITE_MAX_MMAP_SIZE>0
   sqlite3_file *fd = pPager->fd;
-  if( isOpen(fd) ){
+  if( isOpen(fd) && fd->pMethods->iVersion>=3 ){
     sqlite3_int64 sz;
-    pPager->bUseFetch = (fd->pMethods->iVersion>=3) && pPager->szMmap>0;
     sz = pPager->szMmap;
+    pPager->bUseFetch = (sz>0);
     sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz);
   }
 #endif
@@ -41735,9 +41744,12 @@ SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){
 }
 
 /*
-** Adjust the robustness of the database to damage due to OS crashes
-** or power failures by changing the number of syncs()s when writing
-** the rollback journal.  There are three levels:
+** 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.
@@ -41778,22 +41790,21 @@ SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){
 ** and FULL=3.
 */
 #ifndef SQLITE_OMIT_PAGER_PRAGMAS
-SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(
+SQLITE_PRIVATE void sqlite3PagerSetFlags(
   Pager *pPager,        /* The pager to set safety level for */
-  int level,            /* PRAGMA synchronous.  1=OFF, 2=NORMAL, 3=FULL */  
-  int bFullFsync,       /* PRAGMA fullfsync */
-  int bCkptFullFsync    /* PRAGMA checkpoint_fullfsync */
+  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( bFullFsync ){
+  }else if( pgFlags & PAGER_FULLFSYNC ){
     pPager->syncFlags = SQLITE_SYNC_FULL;
     pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
-  }else if( bCkptFullFsync ){
+  }else if( pgFlags & PAGER_CKPT_FULLFSYNC ){
     pPager->syncFlags = SQLITE_SYNC_NORMAL;
     pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
   }else{
@@ -41804,6 +41815,11 @@ SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(
   if( pPager->fullSync ){
     pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS;
   }
+  if( pgFlags & PAGER_CACHESPILL ){
+    pPager->doNotSpill &= ~SPILLFLAG_OFF;
+  }else{
+    pPager->doNotSpill |= SPILLFLAG_OFF;
+  }
 }
 #endif
 
@@ -42546,7 +42562,8 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){
   */
   assert( rc!=SQLITE_OK || isOpen(pPager->fd) );
   if( rc==SQLITE_OK 
-   && (pList->pDirty ? pPager->dbSize : pList->pgno+1)>pPager->dbHintSize 
+   && 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);
@@ -42703,13 +42720,14 @@ static int pagerStress(void *p, PgHdr *pPg){
   assert( pPg->pPager==pPager );
   assert( pPg->flags&PGHDR_DIRTY );
 
-  /* The doNotSyncSpill flag is set during times when doing a sync of
+  /* 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 flag inhibits all cache spilling regardless of whether
-  ** or not a sync is required.  This is set during a rollback.
+  ** 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 implementaton it 
@@ -42719,8 +42737,13 @@ static int pagerStress(void *p, PgHdr *pPg){
   ** test for the error state as a safeguard against future changes.
   */
   if( NEVER(pPager->errCode) ) return SQLITE_OK;
-  if( pPager->doNotSpill ) return SQLITE_OK;
-  if( pPager->doNotSyncSpill && (pPg->flags & PGHDR_NEED_SYNC)!=0 ){
+  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;
   }
 
@@ -43511,7 +43534,7 @@ static void pagerUnlockIfUnused(Pager *pPager){
 ** 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 seperate scenarios:
+** of the page. This occurs in two scenarios:
 **
 **   a) When reading a free-list leaf page from the database, and
 **
@@ -43542,19 +43565,19 @@ 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_ACQUIRE_XXX flags */
+  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_ACQUIRE_NOCONTENT);
+  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_ACQUIRE_READONLY))
+   && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY))
 #ifdef SQLITE_HAS_CODEC
    && pPager->xCodec==0
 #endif
@@ -44074,13 +44097,13 @@ SQLITE_PRIVATE int sqlite3PagerWrite(DbPage *pDbPage){
     int ii;                   /* Loop counter */
     int needSync = 0;         /* True if any page has PGHDR_NEED_SYNC */
 
-    /* Set the doNotSyncSpill flag to 1. This is because we cannot allow
+    /* 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->doNotSyncSpill==0 );
-    pPager->doNotSyncSpill++;
+    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
@@ -44139,8 +44162,8 @@ SQLITE_PRIVATE int sqlite3PagerWrite(DbPage *pDbPage){
       }
     }
 
-    assert( pPager->doNotSyncSpill==1 );
-    pPager->doNotSyncSpill--;
+    assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)!=0 );
+    pPager->doNotSpill &= ~SPILLFLAG_NOSYNC;
   }else{
     rc = pager_write(pDbPage);
   }
@@ -44921,7 +44944,27 @@ SQLITE_PRIVATE void sqlite3PagerSetCodec(
 SQLITE_PRIVATE void *sqlite3PagerGetCodec(Pager *pPager){
   return pPager->pCodec;
 }
-#endif
+
+/*
+** 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;
+}
+
+/*
+** Return the current pager state
+*/
+SQLITE_PRIVATE int sqlite3PagerState(Pager *pPager){
+  return pPager->eState;
+}
+#endif /* SQLITE_HAS_CODEC */
 
 #ifndef SQLITE_OMIT_AUTOVACUUM
 /*
@@ -45476,21 +45519,6 @@ SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){
 }
 #endif
 
-#ifdef SQLITE_HAS_CODEC
-/*
-** 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;
-}
-#endif /* SQLITE_HAS_CODEC */
-
 #endif /* SQLITE_OMIT_DISKIO */
 
 /************** End of pager.c ***********************************************/
@@ -47959,7 +47987,7 @@ SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){
   if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){
     walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
     pWal->writeLock = 0;
-    rc = SQLITE_BUSY;
+    rc = SQLITE_BUSY_SNAPSHOT;
   }
 
   return rc;
@@ -49131,14 +49159,19 @@ struct BtCursor {
 /*
 ** Potential values for BtCursor.eState.
 **
-** CURSOR_VALID:
-**   Cursor points to a valid entry. getPayload() etc. may be called.
-**
 ** CURSOR_INVALID:
 **   Cursor does not point to a valid entry. This can happen (for example) 
 **   because the table is empty or because BtreeCursorFirst() has not been
 **   called.
 **
+** CURSOR_VALID:
+**   Cursor points to a valid entry. getPayload() etc. may be called.
+**
+** CURSOR_SKIPNEXT:
+**   Cursor is valid except that the Cursor.skipNext field is non-zero
+**   indicating that the next sqlite3BtreeNext() or sqlite3BtreePrevious()
+**   operation should be a no-op.
+**
 ** CURSOR_REQUIRESEEK:
 **   The table that this cursor was opened on still exists, but has been 
 **   modified since the cursor was last used. The cursor position is saved
@@ -49155,8 +49188,9 @@ struct BtCursor {
 */
 #define CURSOR_INVALID           0
 #define CURSOR_VALID             1
-#define CURSOR_REQUIRESEEK       2
-#define CURSOR_FAULT             3
+#define CURSOR_SKIPNEXT          2
+#define CURSOR_REQUIRESEEK       3
+#define CURSOR_FAULT             4
 
 /* 
 ** The database page the PENDING_BYTE occupies. This page is never used.
@@ -50270,6 +50304,9 @@ static int btreeRestoreCursorPosition(BtCursor *pCur){
     sqlite3_free(pCur->pKey);
     pCur->pKey = 0;
     assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID );
+    if( pCur->skipNext && pCur->eState==CURSOR_VALID ){
+      pCur->eState = CURSOR_SKIPNEXT;
+    }
   }
   return rc;
 }
@@ -50295,7 +50332,7 @@ SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur, int *pHasMoved){
     *pHasMoved = 1;
     return rc;
   }
-  if( pCur->eState!=CURSOR_VALID || pCur->skipNext!=0 ){
+  if( pCur->eState!=CURSOR_VALID || NEVER(pCur->skipNext!=0) ){
     *pHasMoved = 1;
   }else{
     *pHasMoved = 0;
@@ -50483,7 +50520,8 @@ static void btreeParseCellPtr(
   assert( n==4-4*pPage->leaf );
   if( pPage->intKey ){
     if( pPage->hasData ){
-      n += getVarint32(&pCell[n], nPayload);
+      assert( n==0 );
+      n = getVarint32(pCell, nPayload);
     }else{
       nPayload = 0;
     }
@@ -50761,7 +50799,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
   }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 accomadate it.
+    ** the list that is large enough to accommodate it.
     */
     int pc, addr;
     for(addr=hdr+1; (pc = get2byte(&data[addr]))>0; addr=pc){
@@ -51127,15 +51165,12 @@ static int btreeGetPage(
   BtShared *pBt,       /* The btree */
   Pgno pgno,           /* Number of the page to fetch */
   MemPage **ppPage,    /* Return the page in this parameter */
-  int noContent,       /* Do not load page content if true */
-  int bReadonly        /* True if a read-only (mmap) page is ok */
+  int flags            /* PAGER_GET_NOCONTENT or PAGER_GET_READONLY */
 ){
   int rc;
   DbPage *pDbPage;
-  int flags = (noContent ? PAGER_ACQUIRE_NOCONTENT : 0) 
-            | (bReadonly ? PAGER_ACQUIRE_READONLY : 0);
 
-  assert( noContent==0 || bReadonly==0 );
+  assert( flags==0 || flags==PAGER_GET_NOCONTENT || flags==PAGER_GET_READONLY );
   assert( sqlite3_mutex_held(pBt->mutex) );
   rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, flags);
   if( rc ) return rc;
@@ -51183,15 +51218,16 @@ static int getAndInitPage(
   BtShared *pBt,                  /* The database file */
   Pgno pgno,                      /* Number of the page to get */
   MemPage **ppPage,               /* Write the page pointer here */
-  int bReadonly                   /* True if a read-only (mmap) page is ok */
+  int bReadonly                   /* PAGER_GET_READONLY or 0 */
 ){
   int rc;
   assert( sqlite3_mutex_held(pBt->mutex) );
+  assert( bReadonly==PAGER_GET_READONLY || bReadonly==0 );
 
   if( pgno>btreePagecount(pBt) ){
     rc = SQLITE_CORRUPT_BKPT;
   }else{
-    rc = btreeGetPage(pBt, pgno, ppPage, 0, bReadonly);
+    rc = btreeGetPage(pBt, pgno, ppPage, bReadonly);
     if( rc==SQLITE_OK ){
       rc = btreeInitPage(*ppPage);
       if( rc!=SQLITE_OK ){
@@ -51711,17 +51747,14 @@ SQLITE_PRIVATE int sqlite3BtreeSetMmapLimit(Btree *p, sqlite3_int64 szMmap){
 ** probability of damage to near zero but with a write performance reduction.
 */
 #ifndef SQLITE_OMIT_PAGER_PRAGMAS
-SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(
+SQLITE_PRIVATE int sqlite3BtreeSetPagerFlags(
   Btree *p,              /* The btree to set the safety level on */
-  int level,             /* PRAGMA synchronous.  1=OFF, 2=NORMAL, 3=FULL */
-  int fullSync,          /* PRAGMA fullfsync. */
-  int ckptFullSync       /* PRAGMA checkpoint_fullfync */
+  unsigned pgFlags       /* Various PAGER_* flags */
 ){
   BtShared *pBt = p->pBt;
   assert( sqlite3_mutex_held(p->db->mutex) );
-  assert( level>=1 && level<=3 );
   sqlite3BtreeEnter(p);
-  sqlite3PagerSetSafetyLevel(pBt->pPager, level, fullSync, ckptFullSync);
+  sqlite3PagerSetFlags(pBt->pPager, pgFlags);
   sqlite3BtreeLeave(p);
   return SQLITE_OK;
 }
@@ -51927,7 +51960,7 @@ static int lockBtree(BtShared *pBt){
   assert( pBt->pPage1==0 );
   rc = sqlite3PagerSharedLock(pBt->pPager);
   if( rc!=SQLITE_OK ) return rc;
-  rc = btreeGetPage(pBt, 1, &pPage1, 0, 0);
+  rc = btreeGetPage(pBt, 1, &pPage1, 0);
   if( rc!=SQLITE_OK ) return rc;
 
   /* Do some checking to help insure the file we opened really is
@@ -52509,7 +52542,7 @@ static int relocatePage(
   ** iPtrPage.
   */
   if( eType!=PTRMAP_ROOTPAGE ){
-    rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0, 0);
+    rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0);
     if( rc!=SQLITE_OK ){
       return rc;
     }
@@ -52593,7 +52626,7 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg, int bCommit){
       u8 eMode = BTALLOC_ANY;   /* Mode parameter for allocateBtreePage() */
       Pgno iNear = 0;           /* nearby parameter for allocateBtreePage() */
 
-      rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0, 0);
+      rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0);
       if( rc!=SQLITE_OK ){
         return rc;
       }
@@ -52704,7 +52737,7 @@ SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *p){
 
 /*
 ** This routine is called prior to sqlite3PagerCommit when a transaction
-** is commited for an auto-vacuum database.
+** is committed for an auto-vacuum database.
 **
 ** If SQLITE_OK is returned, then *pnTrunc is set to the number of pages
 ** the database file should be truncated to during the commit process. 
@@ -52819,12 +52852,13 @@ SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zMaster){
 */
 static void btreeEndTransaction(Btree *p){
   BtShared *pBt = p->pBt;
+  sqlite3 *db = p->db;
   assert( sqlite3BtreeHoldsMutex(p) );
 
 #ifndef SQLITE_OMIT_AUTOVACUUM
   pBt->bDoTruncate = 0;
 #endif
-  if( p->inTrans>TRANS_NONE && p->db->activeVdbeCnt>1 ){
+  if( p->inTrans>TRANS_NONE && db->nVdbeRead>1 ){
     /* If there are other active statements that belong to this database
     ** handle, downgrade to a read-only transaction. The other statements
     ** may still be reading from the database.  */
@@ -52991,7 +53025,7 @@ SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p, int tripCode){
     /* The rollback may have destroyed the pPage1->aData value.  So
     ** call btreeGetPage() on page 1 again to make
     ** sure pPage1->aData is set correctly. */
-    if( btreeGetPage(pBt, 1, &pPage1, 0, 0)==SQLITE_OK ){
+    if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
       int nPage = get4byte(28+(u8*)pPage1->aData);
       testcase( nPage==0 );
       if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
@@ -53426,7 +53460,7 @@ static int getOverflowPage(
 
   assert( next==0 || rc==SQLITE_DONE );
   if( rc==SQLITE_OK ){
-    rc = btreeGetPage(pBt, ovfl, &pPage, 0, (ppPage==0));
+    rc = btreeGetPage(pBt, ovfl, &pPage, (ppPage==0) ? PAGER_GET_READONLY : 0);
     assert( rc==SQLITE_OK || pPage==0 );
     if( rc==SQLITE_OK ){
       next = get4byte(pPage->aData);
@@ -53648,7 +53682,7 @@ static int accessPayload(
         {
           DbPage *pDbPage;
           rc = sqlite3PagerAcquire(pBt->pPager, nextPage, &pDbPage,
-              (eOp==0 ? PAGER_ACQUIRE_READONLY : 0)
+              (eOp==0 ? PAGER_GET_READONLY : 0)
           );
           if( rc==SQLITE_OK ){
             aPayload = sqlite3PagerGetData(pDbPage);
@@ -53832,7 +53866,8 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
   if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){
     return SQLITE_CORRUPT_BKPT;
   }
-  rc = getAndInitPage(pBt, newPgno, &pNewPage, (pCur->wrFlag==0));
+  rc = getAndInitPage(pBt, newPgno, &pNewPage,
+               pCur->wrFlag==0 ? PAGER_GET_READONLY : 0);
   if( rc ) return rc;
   pCur->apPage[i+1] = pNewPage;
   pCur->aiIdx[i+1] = 0;
@@ -53949,7 +53984,8 @@ static int moveToRoot(BtCursor *pCur){
     pCur->eState = CURSOR_INVALID;
     return SQLITE_OK;
   }else{
-    rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0], pCur->wrFlag==0);
+    rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0],
+                        pCur->wrFlag==0 ? PAGER_GET_READONLY : 0);
     if( rc!=SQLITE_OK ){
       pCur->eState = CURSOR_INVALID;
       return rc;
@@ -54344,21 +54380,29 @@ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
   MemPage *pPage;
 
   assert( cursorHoldsMutex(pCur) );
-  rc = restoreCursorPosition(pCur);
-  if( rc!=SQLITE_OK ){
-    return rc;
-  }
   assert( pRes!=0 );
-  if( CURSOR_INVALID==pCur->eState ){
-    *pRes = 1;
-    return SQLITE_OK;
-  }
-  if( pCur->skipNext>0 ){
-    pCur->skipNext = 0;
-    *pRes = 0;
-    return SQLITE_OK;
+  assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
+  if( pCur->eState!=CURSOR_VALID ){
+    rc = restoreCursorPosition(pCur);
+    if( rc!=SQLITE_OK ){
+      *pRes = 0;
+      return rc;
+    }
+    if( CURSOR_INVALID==pCur->eState ){
+      *pRes = 1;
+      return SQLITE_OK;
+    }
+    if( pCur->skipNext ){
+      assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT );
+      pCur->eState = CURSOR_VALID;
+      if( pCur->skipNext>0 ){
+        pCur->skipNext = 0;
+        *pRes = 0;
+        return SQLITE_OK;
+      }
+      pCur->skipNext = 0;
+    }
   }
-  pCur->skipNext = 0;
 
   pPage = pCur->apPage[pCur->iPage];
   idx = ++pCur->aiIdx[pCur->iPage];
@@ -54376,7 +54420,10 @@ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
   if( idx>=pPage->nCell ){
     if( !pPage->leaf ){
       rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
-      if( rc ) return rc;
+      if( rc ){
+        *pRes = 0;
+        return rc;
+      }
       rc = moveToLeftmost(pCur);
       *pRes = 0;
       return rc;
@@ -54418,21 +54465,32 @@ SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
   MemPage *pPage;
 
   assert( cursorHoldsMutex(pCur) );
-  rc = restoreCursorPosition(pCur);
-  if( rc!=SQLITE_OK ){
-    return rc;
-  }
+  assert( pRes!=0 );
+  assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
   pCur->atLast = 0;
-  if( CURSOR_INVALID==pCur->eState ){
-    *pRes = 1;
-    return SQLITE_OK;
-  }
-  if( pCur->skipNext<0 ){
-    pCur->skipNext = 0;
-    *pRes = 0;
-    return SQLITE_OK;
+  if( pCur->eState!=CURSOR_VALID ){
+    if( ALWAYS(pCur->eState>=CURSOR_REQUIRESEEK) ){
+      rc = btreeRestoreCursorPosition(pCur);
+      if( rc!=SQLITE_OK ){
+        *pRes = 0;
+        return rc;
+      }
+    }
+    if( CURSOR_INVALID==pCur->eState ){
+      *pRes = 1;
+      return SQLITE_OK;
+    }
+    if( pCur->skipNext ){
+      assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT );
+      pCur->eState = CURSOR_VALID;
+      if( pCur->skipNext<0 ){
+        pCur->skipNext = 0;
+        *pRes = 0;
+        return SQLITE_OK;
+      }
+      pCur->skipNext = 0;
+    }
   }
-  pCur->skipNext = 0;
 
   pPage = pCur->apPage[pCur->iPage];
   assert( pPage->isInit );
@@ -54440,6 +54498,7 @@ SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
     int idx = pCur->aiIdx[pCur->iPage];
     rc = moveToChild(pCur, get4byte(findCell(pPage, idx)));
     if( rc ){
+      *pRes = 0;
       return rc;
     }
     rc = moveToRightmost(pCur);
@@ -54563,7 +54622,7 @@ static int allocateBtreePage(
       if( iTrunk>mxPage ){
         rc = SQLITE_CORRUPT_BKPT;
       }else{
-        rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0, 0);
+        rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
       }
       if( rc ){
         pTrunk = 0;
@@ -54627,7 +54686,7 @@ static int allocateBtreePage(
             goto end_allocate_page;
           }
           testcase( iNewTrunk==mxPage );
-          rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0, 0);
+          rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0);
           if( rc!=SQLITE_OK ){
             goto end_allocate_page;
           }
@@ -54706,8 +54765,8 @@ static int allocateBtreePage(
             memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
           }
           put4byte(&aData[4], k-1);
-          noContent = !btreeGetHasContent(pBt, *pPgno);
-          rc = btreeGetPage(pBt, *pPgno, ppPage, noContent, 0);
+          noContent = !btreeGetHasContent(pBt, *pPgno) ? PAGER_GET_NOCONTENT : 0;
+          rc = btreeGetPage(pBt, *pPgno, ppPage, noContent);
           if( rc==SQLITE_OK ){
             rc = sqlite3PagerWrite((*ppPage)->pDbPage);
             if( rc!=SQLITE_OK ){
@@ -54739,7 +54798,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));
+    int bNoContent = (0==IfNotOmitAV(pBt->bDoTruncate)) ? PAGER_GET_NOCONTENT : 0;
 
     rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
     if( rc ) return rc;
@@ -54755,7 +54814,7 @@ static int allocateBtreePage(
       MemPage *pPg = 0;
       TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage));
       assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) );
-      rc = btreeGetPage(pBt, pBt->nPage, &pPg, bNoContent, 0);
+      rc = btreeGetPage(pBt, pBt->nPage, &pPg, bNoContent);
       if( rc==SQLITE_OK ){
         rc = sqlite3PagerWrite(pPg->pDbPage);
         releasePage(pPg);
@@ -54769,7 +54828,7 @@ static int allocateBtreePage(
     *pPgno = pBt->nPage;
 
     assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
-    rc = btreeGetPage(pBt, *pPgno, ppPage, bNoContent, 0);
+    rc = btreeGetPage(pBt, *pPgno, ppPage, bNoContent);
     if( rc ) return rc;
     rc = sqlite3PagerWrite((*ppPage)->pDbPage);
     if( rc!=SQLITE_OK ){
@@ -54837,7 +54896,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
     /* If the secure_delete option is enabled, then
     ** always fully overwrite deleted information with zeros.
     */
-    if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0, 0))!=0) )
+    if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0) )
      ||            ((rc = sqlite3PagerWrite(pPage->pDbPage))!=0)
     ){
       goto freepage_out;
@@ -54864,7 +54923,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
     u32 nLeaf;                /* Initial number of leaf cells on trunk page */
 
     iTrunk = get4byte(&pPage1->aData[32]);
-    rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0, 0);
+    rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
     if( rc!=SQLITE_OK ){
       goto freepage_out;
     }
@@ -54910,7 +54969,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
   ** first trunk in the free-list is full. Either way, the page being freed
   ** will become the new first trunk page in the free-list.
   */
-  if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0, 0)) ){
+  if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0)) ){
     goto freepage_out;
   }
   rc = sqlite3PagerWrite(pPage->pDbPage);
@@ -56809,7 +56868,7 @@ static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){
       }
 
       /* Move the page currently at pgnoRoot to pgnoMove. */
-      rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0, 0);
+      rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0);
       if( rc!=SQLITE_OK ){
         return rc;
       }
@@ -56830,7 +56889,7 @@ static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){
       if( rc!=SQLITE_OK ){
         return rc;
       }
-      rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0, 0);
+      rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0);
       if( rc!=SQLITE_OK ){
         return rc;
       }
@@ -57008,7 +57067,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
     return SQLITE_LOCKED_SHAREDCACHE;
   }
 
-  rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0, 0);
+  rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
   if( rc ) return rc;
   rc = sqlite3BtreeClearTable(p, iTable, 0);
   if( rc ){
@@ -57043,7 +57102,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
         */
         MemPage *pMove;
         releasePage(pPage);
-        rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0, 0);
+        rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
         if( rc!=SQLITE_OK ){
           return rc;
         }
@@ -57053,7 +57112,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
           return rc;
         }
         pMove = 0;
-        rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0, 0);
+        rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
         freePage(pMove, &rc);
         releasePage(pMove);
         if( rc!=SQLITE_OK ){
@@ -57268,7 +57327,7 @@ static void checkAppendMsg(
   }
   sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap);
   va_end(ap);
-  if( pCheck->errMsg.mallocFailed ){
+  if( pCheck->errMsg.accError==STRACCUM_NOMEM ){
     pCheck->mallocFailed = 1;
   }
 }
@@ -57465,7 +57524,7 @@ static int checkTreePage(
   usableSize = pBt->usableSize;
   if( iPage==0 ) return 0;
   if( checkRef(pCheck, iPage, zParentContext) ) return 0;
-  if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0, 0))!=0 ){
+  if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
     checkAppendMsg(pCheck, zContext,
        "unable to get the page. error code=%d", rc);
     return 0;
@@ -58047,12 +58106,6 @@ SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *pCsr, unsigned int mask){
 ** API functions and the related features.
 */
 
-/* Macro to find the minimum of two numeric values.
-*/
-#ifndef MIN
-# define MIN(x,y) ((x)<(y)?(x):(y))
-#endif
-
 /*
 ** Structure allocated for each backup operation.
 */
@@ -58430,7 +58483,7 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
       if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
         DbPage *pSrcPg;                             /* Source page object */
         rc = sqlite3PagerAcquire(pSrcPager, iSrcPg, &pSrcPg,
-                                 PAGER_ACQUIRE_READONLY);
+                                 PAGER_GET_READONLY);
         if( rc==SQLITE_OK ){
           rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0);
           sqlite3PagerUnref(pSrcPg);
@@ -59585,34 +59638,29 @@ SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const C
   ** if both values are integers.
   */
   if( combined_flags&(MEM_Int|MEM_Real) ){
-    if( !(f1&(MEM_Int|MEM_Real)) ){
-      return 1;
-    }
-    if( !(f2&(MEM_Int|MEM_Real)) ){
-      return -1;
-    }
-    if( (f1 & f2 & MEM_Int)==0 ){
-      double r1, r2;
-      if( (f1&MEM_Real)==0 ){
-        r1 = (double)pMem1->u.i;
-      }else{
-        r1 = pMem1->r;
-      }
-      if( (f2&MEM_Real)==0 ){
-        r2 = (double)pMem2->u.i;
-      }else{
-        r2 = pMem2->r;
-      }
-      if( r1<r2 ) return -1;
-      if( r1>r2 ) return 1;
-      return 0;
-    }else{
-      assert( f1&MEM_Int );
-      assert( f2&MEM_Int );
+    double r1, r2;
+    if( (f1 & f2 & MEM_Int)!=0 ){
       if( pMem1->u.i < pMem2->u.i ) return -1;
       if( pMem1->u.i > pMem2->u.i ) return 1;
       return 0;
     }
+    if( (f1&MEM_Real)!=0 ){
+      r1 = pMem1->r;
+    }else if( (f1&MEM_Int)!=0 ){
+      r1 = (double)pMem1->u.i;
+    }else{
+      return 1;
+    }
+    if( (f2&MEM_Real)!=0 ){
+      r2 = pMem2->r;
+    }else if( (f2&MEM_Int)!=0 ){
+      r2 = (double)pMem2->u.i;
+    }else{
+      return -1;
+    }
+    if( r1<r2 ) return -1;
+    if( r1>r2 ) return 1;
+    return 0;
   }
 
   /* If one value is a string and the other is a blob, the string is less.
@@ -60198,8 +60246,8 @@ SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe *p){
 SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *p, int x){
   int j = -1-x;
   assert( p->magic==VDBE_MAGIC_INIT );
-  assert( j>=0 && j<p->nLabel );
-  if( p->aLabel ){
+  assert( j<p->nLabel );
+  if( j>=0 && p->aLabel ){
     p->aLabel[j] = p->nOp;
   }
 }
@@ -60351,32 +60399,64 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
   Op *pOp;
   int *aLabel = p->aLabel;
   p->readOnly = 1;
+  p->bIsReader = 0;
   for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
     u8 opcode = pOp->opcode;
 
-    pOp->opflags = sqlite3OpcodeProperty[opcode];
-    if( opcode==OP_Function || opcode==OP_AggStep ){
-      if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;
-    }else if( (opcode==OP_Transaction && pOp->p2!=0) || opcode==OP_Vacuum ){
-      p->readOnly = 0;
+    /* NOTE: Be sure to update mkopcodeh.awk when adding or removing
+    ** cases from this switch! */
+    switch( opcode ){
+      case OP_Function:
+      case OP_AggStep: {
+        if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;
+        break;
+      }
+      case OP_Transaction: {
+        if( pOp->p2!=0 ) p->readOnly = 0;
+        /* fall thru */
+      }
+      case OP_AutoCommit:
+      case OP_Savepoint: {
+        p->bIsReader = 1;
+        break;
+      }
+#ifndef SQLITE_OMIT_WAL
+      case OP_Checkpoint:
+#endif
+      case OP_Vacuum:
+      case OP_JournalMode: {
+        p->readOnly = 0;
+        p->bIsReader = 1;
+        break;
+      }
 #ifndef SQLITE_OMIT_VIRTUALTABLE
-    }else if( opcode==OP_VUpdate ){
-      if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
-    }else if( opcode==OP_VFilter ){
-      int n;
-      assert( p->nOp - i >= 3 );
-      assert( pOp[-1].opcode==OP_Integer );
-      n = pOp[-1].p1;
-      if( n>nMaxArgs ) nMaxArgs = n;
+      case OP_VUpdate: {
+        if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
+        break;
+      }
+      case OP_VFilter: {
+        int n;
+        assert( p->nOp - i >= 3 );
+        assert( pOp[-1].opcode==OP_Integer );
+        n = pOp[-1].p1;
+        if( n>nMaxArgs ) nMaxArgs = n;
+        break;
+      }
 #endif
-    }else if( opcode==OP_Next || opcode==OP_SorterNext ){
-      pOp->p4.xAdvance = sqlite3BtreeNext;
-      pOp->p4type = P4_ADVANCE;
-    }else if( opcode==OP_Prev ){
-      pOp->p4.xAdvance = sqlite3BtreePrevious;
-      pOp->p4type = P4_ADVANCE;
+      case OP_Next:
+      case OP_SorterNext: {
+        pOp->p4.xAdvance = sqlite3BtreeNext;
+        pOp->p4type = P4_ADVANCE;
+        break;
+      }
+      case OP_Prev: {
+        pOp->p4.xAdvance = sqlite3BtreePrevious;
+        pOp->p4type = P4_ADVANCE;
+        break;
+      }
     }
 
+    pOp->opflags = sqlite3OpcodeProperty[opcode];
     if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
       assert( -1-pOp->p2<p->nLabel );
       pOp->p2 = aLabel[-1-pOp->p2];
@@ -60384,8 +60464,8 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
   }
   sqlite3DbFree(p->db, p->aLabel);
   p->aLabel = 0;
-
   *pMaxFuncArgs = nMaxArgs;
+  assert( p->bIsReader!=0 || p->btreeMask==0 );
 }
 
 /*
@@ -60511,8 +60591,7 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u8 val){
 ** the address of the next instruction to be coded.
 */
 SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
-  assert( addr>=0 || p->db->mallocFailed );
-  if( addr>=0 ) sqlite3VdbeChangeP2(p, addr, p->nOp);
+  if( ALWAYS(addr>=0) ) sqlite3VdbeChangeP2(p, addr, p->nOp);
 }
 
 
@@ -60548,13 +60627,6 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){
         if( db->pnBytesFreed==0 ) sqlite3_free(p4);
         break;
       }
-      case P4_VDBEFUNC: {
-        VdbeFunc *pVdbeFunc = (VdbeFunc *)p4;
-        freeEphemeralFunction(db, pVdbeFunc->pFunc);
-        if( db->pnBytesFreed==0 ) sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
-        sqlite3DbFree(db, pVdbeFunc);
-        break;
-      }
       case P4_FUNCDEF: {
         freeEphemeralFunction(db, (FuncDef*)p4);
         break;
@@ -60673,20 +60745,13 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int
     pOp->p4.p = 0;
     pOp->p4type = P4_NOTUSED;
   }else if( n==P4_KEYINFO ){
-    KeyInfo *pKeyInfo;
-    int nField, nByte;
-
-    nField = ((KeyInfo*)zP4)->nField;
-    nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]) + nField;
-    pKeyInfo = sqlite3DbMallocRaw(0, nByte);
-    pOp->p4.pKeyInfo = pKeyInfo;
-    if( pKeyInfo ){
-      u8 *aSortOrder;
-      memcpy((char*)pKeyInfo, zP4, nByte - nField);
-      aSortOrder = pKeyInfo->aSortOrder;
-      assert( aSortOrder!=0 );
-      pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField];
-      memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
+    KeyInfo *pOrig, *pNew;
+
+    pOrig = (KeyInfo*)zP4;
+    pOp->p4.pKeyInfo = pNew = sqlite3KeyInfoAlloc(db, pOrig->nField);
+    if( pNew ){
+      memcpy(pNew->aColl, pOrig->aColl, pOrig->nField*sizeof(pNew->aColl[0]));
+      memcpy(pNew->aSortOrder, pOrig->aSortOrder, pOrig->nField);
       pOp->p4type = P4_KEYINFO;
     }else{
       p->db->mallocFailed = 1;
@@ -61584,6 +61649,10 @@ static void closeAllCursors(Vdbe *p){
     p->pDelFrame = pDel->pParent;
     sqlite3VdbeFrameDelete(pDel);
   }
+
+  /* Delete any auxdata allocations made by the VM */
+  sqlite3VdbeDeleteAuxData(p, -1, 0);
+  assert( p->pAuxData==0 );
 }
 
 /*
@@ -61692,7 +61761,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
   ** required, as an xSync() callback may add an attached database
   ** to the transaction.
   */
-  rc = sqlite3VtabSync(db, &p->zErrMsg);
+  rc = sqlite3VtabSync(db, p);
 
   /* This loop determines (a) if the commit hook should be invoked and
   ** (b) how many database files have open write transactions, not 
@@ -61911,7 +61980,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
 }
 
 /* 
-** This routine checks that the sqlite3.activeVdbeCnt count variable
+** This routine checks that the sqlite3.nVdbeActive count variable
 ** matches the number of vdbe's in the list sqlite3.pVdbe that are
 ** currently active. An assertion fails if the two counts do not match.
 ** This is an internal self-check only - it is not an essential processing
@@ -61924,16 +61993,19 @@ static void checkActiveVdbeCnt(sqlite3 *db){
   Vdbe *p;
   int cnt = 0;
   int nWrite = 0;
+  int nRead = 0;
   p = db->pVdbe;
   while( p ){
     if( p->magic==VDBE_MAGIC_RUN && p->pc>=0 ){
       cnt++;
       if( p->readOnly==0 ) nWrite++;
+      if( p->bIsReader ) nRead++;
     }
     p = p->pNext;
   }
-  assert( cnt==db->activeVdbeCnt );
-  assert( nWrite==db->writeVdbeCnt );
+  assert( cnt==db->nVdbeActive );
+  assert( nWrite==db->nVdbeWrite );
+  assert( nRead==db->nVdbeRead );
 }
 #else
 #define checkActiveVdbeCnt(x)
@@ -61944,7 +62016,7 @@ static void checkActiveVdbeCnt(sqlite3 *db){
 ** close it now. Argument eOp must be either SAVEPOINT_ROLLBACK or
 ** SAVEPOINT_RELEASE. If it is SAVEPOINT_ROLLBACK, then the statement
 ** transaction is rolled back. If eOp is SAVEPOINT_RELEASE, then the 
-** statement transaction is commtted.
+** statement transaction is committed.
 **
 ** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned. 
 ** Otherwise SQLITE_OK.
@@ -61998,6 +62070,7 @@ SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){
     ** the statement transaction was opened.  */
     if( eOp==SAVEPOINT_ROLLBACK ){
       db->nDeferredCons = p->nStmtDefCons;
+      db->nDeferredImmCons = p->nStmtDefImmCons;
     }
   }
   return rc;
@@ -62016,7 +62089,9 @@ SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){
 #ifndef SQLITE_OMIT_FOREIGN_KEY
 SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *p, int deferred){
   sqlite3 *db = p->db;
-  if( (deferred && db->nDeferredCons>0) || (!deferred && p->nFkConstraint>0) ){
+  if( (deferred && (db->nDeferredCons+db->nDeferredImmCons)>0) 
+   || (!deferred && p->nFkConstraint>0) 
+  ){
     p->rc = SQLITE_CONSTRAINT_FOREIGNKEY;
     p->errorAction = OE_Abort;
     sqlite3SetString(&p->zErrMsg, db, "foreign key constraint failed");
@@ -62069,8 +62144,9 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
   }
   checkActiveVdbeCnt(db);
 
-  /* No commit or rollback needed if the program never started */
-  if( p->pc>=0 ){
+  /* No commit or rollback needed if the program never started or if the
+  ** SQL statement does not read or write a database file.  */
+  if( p->pc>=0 && p->bIsReader ){
     int mrc;   /* Primary error code from p->rc */
     int eStatementOp = 0;
     int isSpecialError;            /* Set to true if a 'special' error */
@@ -62123,7 +62199,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
     */
     if( !sqlite3VtabInSync(db) 
      && db->autoCommit 
-     && db->writeVdbeCnt==(p->readOnly==0) 
+     && db->nVdbeWrite==(p->readOnly==0) 
     ){
       if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
         rc = sqlite3VdbeCheckFk(p, 1);
@@ -62148,6 +62224,8 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
           sqlite3RollbackAll(db, SQLITE_OK);
         }else{
           db->nDeferredCons = 0;
+          db->nDeferredImmCons = 0;
+          db->flags &= ~SQLITE_DeferFKs;
           sqlite3CommitInternalChanges(db);
         }
       }else{
@@ -62204,11 +62282,12 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
 
   /* We have successfully halted and closed the VM.  Record this fact. */
   if( p->pc>=0 ){
-    db->activeVdbeCnt--;
-    if( !p->readOnly ){
-      db->writeVdbeCnt--;
-    }
-    assert( db->activeVdbeCnt>=db->writeVdbeCnt );
+    db->nVdbeActive--;
+    if( !p->readOnly ) db->nVdbeWrite--;
+    if( p->bIsReader ) db->nVdbeRead--;
+    assert( db->nVdbeActive>=db->nVdbeRead );
+    assert( db->nVdbeRead>=db->nVdbeWrite );
+    assert( db->nVdbeWrite>=0 );
   }
   p->magic = VDBE_MAGIC_HALT;
   checkActiveVdbeCnt(db);
@@ -62224,7 +62303,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
     sqlite3ConnectionUnlocked(db);
   }
 
-  assert( db->activeVdbeCnt>0 || db->autoCommit==0 || db->nStatement==0 );
+  assert( db->nVdbeActive>0 || db->autoCommit==0 || db->nStatement==0 );
   return (p->rc==SQLITE_BUSY ? SQLITE_BUSY : SQLITE_OK);
 }
 
@@ -62372,20 +62451,35 @@ SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe *p){
 }
 
 /*
-** Call the destructor for each auxdata entry in pVdbeFunc for which
-** the corresponding bit in mask is clear.  Auxdata entries beyond 31
-** are always destroyed.  To destroy all auxdata entries, call this
-** routine with mask==0.
+** If parameter iOp is less than zero, then invoke the destructor for
+** all auxiliary data pointers currently cached by the VM passed as
+** the first argument.
+**
+** Or, if iOp is greater than or equal to zero, then the destructor is
+** only invoked for those auxiliary data pointers created by the user 
+** function invoked by the OP_Function opcode at instruction iOp of 
+** VM pVdbe, and only then if:
+**
+**    * the associated function parameter is the 32nd or later (counting
+**      from left to right), or
+**
+**    * the corresponding bit in argument mask is clear (where the first
+**      function parameter corrsponds to bit 0 etc.).
 */
-SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){
-  int i;
-  for(i=0; i<pVdbeFunc->nAux; i++){
-    struct AuxData *pAux = &pVdbeFunc->apAux[i];
-    if( (i>31 || !(mask&(((u32)1)<<i))) && pAux->pAux ){
+SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe *pVdbe, int iOp, int mask){
+  AuxData **pp = &pVdbe->pAuxData;
+  while( *pp ){
+    AuxData *pAux = *pp;
+    if( (iOp<0)
+     || (pAux->iOp==iOp && (pAux->iArg>31 || !(mask & ((u32)1<<pAux->iArg))))
+    ){
       if( pAux->xDelete ){
         pAux->xDelete(pAux->pAux);
       }
-      pAux->pAux = 0;
+      *pp = pAux->pNext;
+      sqlite3DbFree(pVdbe->db, pAux);
+    }else{
+      pp= &pAux->pNext;
     }
   }
 }
@@ -62904,11 +62998,10 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
   int nKey1, const void *pKey1, /* Left key */
   UnpackedRecord *pPKey2        /* Right key */
 ){
-  int d1;            /* Offset into aKey[] of next data element */
+  u32 d1;            /* Offset into aKey[] of next data element */
   u32 idx1;          /* Offset into aKey[] of next header element */
   u32 szHdr1;        /* Number of bytes in header */
   int i = 0;
-  int nField;
   int rc = 0;
   const unsigned char *aKey1 = (const unsigned char *)pKey1;
   KeyInfo *pKeyInfo;
@@ -62931,14 +63024,25 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
   
   idx1 = getVarint32(aKey1, szHdr1);
   d1 = szHdr1;
-  nField = pKeyInfo->nField;
+  assert( pKeyInfo->nField+1>=pPKey2->nField );
   assert( pKeyInfo->aSortOrder!=0 );
   while( idx1<szHdr1 && i<pPKey2->nField ){
     u32 serial_type1;
 
     /* Read the serial types for the next element in each key. */
     idx1 += getVarint32( aKey1+idx1, serial_type1 );
-    if( d1>=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break;
+
+    /* Verify that there is enough key space remaining to avoid
+    ** a buffer overread.  The "d1+serial_type1+2" subexpression will
+    ** always be greater than or equal to the amount of required key space.
+    ** Use that approximation to avoid the more expensive call to
+    ** sqlite3VdbeSerialTypeLen() in the common case.
+    */
+    if( d1+serial_type1+2>(u32)nKey1
+     && d1+sqlite3VdbeSerialTypeLen(serial_type1)>(u32)nKey1 
+    ){
+      break;
+    }
 
     /* Extract the values to be compared.
     */
@@ -62946,13 +63050,12 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
 
     /* Do the comparison
     */
-    rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i],
-                           i<nField ? pKeyInfo->aColl[i] : 0);
+    rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], pKeyInfo->aColl[i]);
     if( rc!=0 ){
       assert( mem1.zMalloc==0 );  /* See comment below */
 
       /* Invert the result if we are using DESC sort order. */
-      if( i<nField && pKeyInfo->aSortOrder[i] ){
+      if( pKeyInfo->aSortOrder[i] ){
         rc = -rc;
       }
     
@@ -63167,7 +63270,7 @@ SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe *v){
 **
 ** The returned value must be freed by the caller using sqlite3ValueFree().
 */
-SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetValue(Vdbe *v, int iVar, u8 aff){
+SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){
   assert( iVar>0 );
   if( v ){
     Mem *pMem = &v->aVar[iVar-1];
@@ -63198,6 +63301,21 @@ SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
   }
 }
 
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+/*
+** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored
+** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored
+** in memory obtained from sqlite3DbMalloc).
+*/
+SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe *p, sqlite3_vtab *pVtab){
+  sqlite3 *db = p->db;
+  sqlite3DbFree(db, p->zErrMsg);
+  p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg);
+  sqlite3_free(pVtab->zErrMsg);
+  pVtab->zErrMsg = 0;
+}
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
+
 /************** End of vdbeaux.c *********************************************/
 /************** Begin file vdbeapi.c *****************************************/
 /*
@@ -63411,12 +63529,14 @@ SQLITE_API void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
 SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
   assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
   pCtx->isError = SQLITE_ERROR;
+  pCtx->fErrorOrAux = 1;
   sqlite3VdbeMemSetStr(&pCtx->s, 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) );
   pCtx->isError = SQLITE_ERROR;
+  pCtx->fErrorOrAux = 1;
   sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
 }
 #endif
@@ -63480,6 +63600,7 @@ SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
 }
 SQLITE_API void 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, 
                          SQLITE_UTF8, SQLITE_STATIC);
@@ -63490,6 +63611,7 @@ SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
 SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){
   assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
   pCtx->isError = SQLITE_TOOBIG;
+  pCtx->fErrorOrAux = 1;
   sqlite3VdbeMemSetStr(&pCtx->s, "string or blob too big", -1, 
                        SQLITE_UTF8, SQLITE_STATIC);
 }
@@ -63499,6 +63621,7 @@ SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){
   assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
   sqlite3VdbeMemSetNull(&pCtx->s);
   pCtx->isError = SQLITE_NOMEM;
+  pCtx->fErrorOrAux = 1;
   pCtx->s.db->mallocFailed = 1;
 }
 
@@ -63582,11 +63705,13 @@ static int sqlite3Step(Vdbe *p){
     ** reset the interrupt flag.  This prevents a call to sqlite3_interrupt
     ** from interrupting a statement that has not yet started.
     */
-    if( db->activeVdbeCnt==0 ){
+    if( db->nVdbeActive==0 ){
       db->u1.isInterrupted = 0;
     }
 
-    assert( db->writeVdbeCnt>0 || db->autoCommit==0 || db->nDeferredCons==0 );
+    assert( db->nVdbeWrite>0 || db->autoCommit==0 
+        || (db->nDeferredCons==0 && db->nDeferredImmCons==0)
+    );
 
 #ifndef SQLITE_OMIT_TRACE
     if( db->xProfile && !db->init.busy ){
@@ -63594,8 +63719,9 @@ static int sqlite3Step(Vdbe *p){
     }
 #endif
 
-    db->activeVdbeCnt++;
-    if( p->readOnly==0 ) db->writeVdbeCnt++;
+    db->nVdbeActive++;
+    if( p->readOnly==0 ) db->nVdbeWrite++;
+    if( p->bIsReader ) db->nVdbeRead++;
     p->pc = 0;
   }
 #ifndef SQLITE_OMIT_EXPLAIN
@@ -63604,9 +63730,9 @@ static int sqlite3Step(Vdbe *p){
   }else
 #endif /* SQLITE_OMIT_EXPLAIN */
   {
-    db->vdbeExecCnt++;
+    db->nVdbeExec++;
     rc = sqlite3VdbeExec(p);
-    db->vdbeExecCnt--;
+    db->nVdbeExec--;
   }
 
 #ifndef SQLITE_OMIT_TRACE
@@ -63781,14 +63907,14 @@ SQLITE_API void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
 ** the user-function defined by pCtx.
 */
 SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
-  VdbeFunc *pVdbeFunc;
+  AuxData *pAuxData;
 
   assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
-  pVdbeFunc = pCtx->pVdbeFunc;
-  if( !pVdbeFunc || iArg>=pVdbeFunc->nAux || iArg<0 ){
-    return 0;
+  for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
+    if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
   }
-  return pVdbeFunc->apAux[iArg].pAux;
+
+  return (pAuxData ? pAuxData->pAux : 0);
 }
 
 /*
@@ -63802,29 +63928,30 @@ SQLITE_API void sqlite3_set_auxdata(
   void *pAux, 
   void (*xDelete)(void*)
 ){
-  struct AuxData *pAuxData;
-  VdbeFunc *pVdbeFunc;
-  if( iArg<0 ) goto failed;
+  AuxData *pAuxData;
+  Vdbe *pVdbe = pCtx->pVdbe;
 
   assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
-  pVdbeFunc = pCtx->pVdbeFunc;
-  if( !pVdbeFunc || pVdbeFunc->nAux<=iArg ){
-    int nAux = (pVdbeFunc ? pVdbeFunc->nAux : 0);
-    int nMalloc = sizeof(VdbeFunc) + sizeof(struct AuxData)*iArg;
-    pVdbeFunc = sqlite3DbRealloc(pCtx->s.db, pVdbeFunc, nMalloc);
-    if( !pVdbeFunc ){
-      goto failed;
-    }
-    pCtx->pVdbeFunc = pVdbeFunc;
-    memset(&pVdbeFunc->apAux[nAux], 0, sizeof(struct AuxData)*(iArg+1-nAux));
-    pVdbeFunc->nAux = iArg+1;
-    pVdbeFunc->pFunc = pCtx->pFunc;
-  }
+  if( iArg<0 ) goto failed;
 
-  pAuxData = &pVdbeFunc->apAux[iArg];
-  if( pAuxData->pAux && pAuxData->xDelete ){
+  for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
+    if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
+  }
+  if( pAuxData==0 ){
+    pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData));
+    if( !pAuxData ) goto failed;
+    pAuxData->iOp = pCtx->iOp;
+    pAuxData->iArg = iArg;
+    pAuxData->pNext = pVdbe->pAuxData;
+    pVdbe->pAuxData = pAuxData;
+    if( pCtx->fErrorOrAux==0 ){
+      pCtx->isError = 0;
+      pCtx->fErrorOrAux = 1;
+    }
+  }else if( pAuxData->xDelete ){
     pAuxData->xDelete(pAuxData->pAux);
   }
+
   pAuxData->pAux = pAux;
   pAuxData->xDelete = xDelete;
   return;
@@ -64013,13 +64140,6 @@ SQLITE_API int sqlite3_column_type(sqlite3_stmt *pStmt, int i){
   return iType;
 }
 
-/* The following function is experimental and subject to change or
-** removal */
-/*int sqlite3_column_numeric_type(sqlite3_stmt *pStmt, int i){
-**  return sqlite3_value_numeric_type( columnMem(pStmt,i) );
-**}
-*/
-
 /*
 ** Convert the N-th element of pStmt->pColName[] into a string using
 ** xFunc() then return that string.  If N is out of range, return 0.
@@ -64496,9 +64616,9 @@ SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
 */
 SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
   Vdbe *pVdbe = (Vdbe*)pStmt;
-  int v = pVdbe->aCounter[op-1];
-  if( resetFlag ) pVdbe->aCounter[op-1] = 0;
-  return v;
+  u32 v = pVdbe->aCounter[op];
+  if( resetFlag ) pVdbe->aCounter[op] = 0;
+  return (int)v;
 }
 
 /************** End of vdbeapi.c *********************************************/
@@ -64550,9 +64670,9 @@ static int findNextHostParameter(const char *zSql, int *pnToken){
 
 /*
 ** This function returns a pointer to a nul-terminated string in memory
-** obtained from sqlite3DbMalloc(). If sqlite3.vdbeExecCnt is 1, then the
+** obtained from sqlite3DbMalloc(). If sqlite3.nVdbeExec is 1, then the
 ** string contains a copy of zRawSql but with host parameters expanded to 
-** their current bindings. Or, if sqlite3.vdbeExecCnt is greater than 1, 
+** their current bindings. Or, if sqlite3.nVdbeExec is greater than 1, 
 ** then the returned string holds a copy of zRawSql with "-- " prepended
 ** to each line of text.
 **
@@ -64590,7 +64710,7 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
   sqlite3StrAccumInit(&out, zBase, sizeof(zBase), 
                       db->aLimit[SQLITE_LIMIT_LENGTH]);
   out.db = db;
-  if( db->vdbeExecCnt>1 ){
+  if( db->nVdbeExec>1 ){
     while( *zRawSql ){
       const char *zStart = zRawSql;
       while( *(zRawSql++)!='\n' && *zRawSql );
@@ -65385,19 +65505,6 @@ static int checkSavepointCount(sqlite3 *db){
 }
 #endif
 
-/*
-** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored
-** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored
-** in memory obtained from sqlite3DbMalloc).
-*/
-static void importVtabErrMsg(Vdbe *p, sqlite3_vtab *pVtab){
-  sqlite3 *db = p->db;
-  sqlite3DbFree(db, p->zErrMsg);
-  p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg);
-  sqlite3_free(pVtab->zErrMsg);
-  pVtab->zErrMsg = 0;
-}
-
 
 /*
 ** Execute as much of a VDBE program as we can then return.
@@ -65440,16 +65547,16 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
   sqlite3 *db = p->db;       /* The database */
   u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
   u8 encoding = ENC(db);     /* The database encoding */
+  int iCompare = 0;          /* Result of last OP_Compare operation */
+  unsigned nVmStep = 0;      /* Number of virtual machine steps */
 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
-  int checkProgress;         /* True if progress callbacks are enabled */
-  int nProgressOps = 0;      /* Opcodes executed since progress callback. */
+  unsigned nProgressLimit = 0;/* Invoke xProgress() when nVmStep reaches this */
 #endif
   Mem *aMem = p->aMem;       /* Copy of p->aMem */
   Mem *pIn1 = 0;             /* 1st input operand */
   Mem *pIn2 = 0;             /* 2nd input operand */
   Mem *pIn3 = 0;             /* 3rd input operand */
   Mem *pOut = 0;             /* Output operand */
-  int iCompare = 0;          /* Result of last OP_Compare operation */
   int *aPermute = 0;         /* Permutation of columns for OP_Compare */
   i64 lastRowid = db->lastRowid;  /* Saved value of the last insert ROWID */
 #ifdef VDBE_PROFILE
@@ -65895,6 +66002,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
     goto no_mem;
   }
   assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
+  assert( p->bIsReader || p->readOnly!=0 );
   p->rc = SQLITE_OK;
   assert( p->explain==0 );
   p->pResultSet = 0;
@@ -65902,7 +66010,15 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
   CHECK_FOR_INTERRUPT;
   sqlite3VdbeIOTraceSql(p);
 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
-  checkProgress = db->xProgress!=0;
+  if( db->xProgress ){
+    assert( 0 < db->nProgressOps );
+    nProgressLimit = (unsigned)p->aCounter[SQLITE_STMTSTATUS_VM_STEP];
+    if( nProgressLimit==0 ){
+      nProgressLimit = db->nProgressOps;
+    }else{
+      nProgressLimit %= (unsigned)db->nProgressOps;
+    }
+  }
 #endif
 #ifdef SQLITE_DEBUG
   sqlite3BeginBenignMalloc();
@@ -65923,6 +66039,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
     origPc = pc;
     start = sqlite3Hwtime();
 #endif
+    nVmStep++;
     pOp = &aOp[pc];
 
     /* Only allow tracing if SQLITE_DEBUG is defined.
@@ -65950,27 +66067,6 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
     }
 #endif
 
-#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
-    /* Call the progress callback if it is configured and the required number
-    ** of VDBE ops have been executed (either since this invocation of
-    ** sqlite3VdbeExec() or since last time the progress callback was called).
-    ** If the progress callback returns non-zero, exit the virtual machine with
-    ** a return code SQLITE_ABORT.
-    */
-    if( checkProgress ){
-      if( db->nProgressOps==nProgressOps ){
-        int prc;
-        prc = db->xProgress(db->pProgressArg);
-        if( prc!=0 ){
-          rc = SQLITE_INTERRUPT;
-          goto vdbe_error_halt;
-        }
-        nProgressOps = 0;
-      }
-      nProgressOps++;
-    }
-#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
@@ -66063,8 +66159,40 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
 ** the program.
 */
 case OP_Goto: {             /* jump */
-  CHECK_FOR_INTERRUPT;
   pc = 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
+  ** completion.  Check to see if sqlite3_interrupt() has been called
+  ** or if the progress callback needs to be invoked. 
+  **
+  ** This code uses unstructured "goto" statements and does not look clean.
+  ** But that is not due to sloppy coding habits. The code is written this
+  ** way for performance, to avoid having to run the interrupt and progress
+  ** checks on every opcode.  This helps sqlite3_step() to run about 1.5%
+  ** faster according to "valgrind --tool=cachegrind" */
+check_for_interrupt:
+  CHECK_FOR_INTERRUPT;
+#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
+  /* Call the progress callback if it is configured and the required number
+  ** of VDBE ops have been executed (either since this invocation of
+  ** sqlite3VdbeExec() or since last time the progress callback was called).
+  ** If the progress callback returns non-zero, exit the virtual machine with
+  ** a return code SQLITE_ABORT.
+  */
+  if( db->xProgress!=0 && nVmStep>=nProgressLimit ){
+    int prc;
+    prc = db->xProgress(db->pProgressArg);
+    if( prc!=0 ){
+      rc = SQLITE_INTERRUPT;
+      goto vdbe_error_halt;
+    }
+    if( db->xProgress!=0 ){
+      nProgressLimit = nVmStep + db->nProgressOps - (nVmStep%db->nProgressOps);
+    }
+  }
+#endif
+  
   break;
 }
 
@@ -66185,7 +66313,7 @@ case OP_Halt: {
     p->rc = rc = SQLITE_BUSY;
   }else{
     assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT );
-    assert( rc==SQLITE_OK || db->nDeferredCons>0 );
+    assert( rc==SQLITE_OK || db->nDeferredCons>0 || db->nDeferredImmCons>0 );
     rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
   }
   goto vdbe_return;
@@ -66747,19 +66875,14 @@ case OP_Function: {
     REGISTER_TRACE(pOp->p2+u.ai.i, u.ai.pArg);
   }
 
-  assert( pOp->p4type==P4_FUNCDEF || pOp->p4type==P4_VDBEFUNC );
-  if( pOp->p4type==P4_FUNCDEF ){
-    u.ai.ctx.pFunc = pOp->p4.pFunc;
-    u.ai.ctx.pVdbeFunc = 0;
-  }else{
-    u.ai.ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.pVdbeFunc;
-    u.ai.ctx.pFunc = u.ai.ctx.pVdbeFunc->pFunc;
-  }
-
+  assert( pOp->p4type==P4_FUNCDEF );
+  u.ai.ctx.pFunc = pOp->p4.pFunc;
   u.ai.ctx.s.flags = MEM_Null;
   u.ai.ctx.s.db = db;
   u.ai.ctx.s.xDel = 0;
   u.ai.ctx.s.zMalloc = 0;
+  u.ai.ctx.iOp = pc;
+  u.ai.ctx.pVdbe = p;
 
   /* The output cell may already have a buffer allocated. Move
   ** the pointer to u.ai.ctx.s so in case the user-function can use
@@ -66768,7 +66891,7 @@ case OP_Function: {
   sqlite3VdbeMemMove(&u.ai.ctx.s, pOut);
   MemSetTypeFlag(&u.ai.ctx.s, MEM_Null);
 
-  u.ai.ctx.isError = 0;
+  u.ai.ctx.fErrorOrAux = 0;
   if( u.ai.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
     assert( pOp>aOp );
     assert( pOp[-1].p4type==P4_COLLSEQ );
@@ -66779,15 +66902,6 @@ case OP_Function: {
   (*u.ai.ctx.pFunc->xFunc)(&u.ai.ctx, u.ai.n, u.ai.apVal); /* IMP: R-24505-23230 */
   lastRowid = db->lastRowid;
 
-  /* If any auxiliary data functions have been called by this user function,
-  ** immediately call the destructor for any non-static values.
-  */
-  if( u.ai.ctx.pVdbeFunc ){
-    sqlite3VdbeDeleteAuxData(u.ai.ctx.pVdbeFunc, pOp->p1);
-    pOp->p4.pVdbeFunc = u.ai.ctx.pVdbeFunc;
-    pOp->p4type = P4_VDBEFUNC;
-  }
-
   if( db->mallocFailed ){
     /* Even though a malloc() has failed, the implementation of the
     ** user function may have called an sqlite3_result_XXX() function
@@ -66799,9 +66913,12 @@ case OP_Function: {
   }
 
   /* If the function returned an error, throw an exception */
-  if( u.ai.ctx.isError ){
-    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ai.ctx.s));
-    rc = u.ai.ctx.isError;
+  if( u.ai.ctx.fErrorOrAux ){
+    if( u.ai.ctx.isError ){
+      sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ai.ctx.s));
+      rc = u.ai.ctx.isError;
+    }
+    sqlite3VdbeDeleteAuxData(p, pc, pOp->p1);
   }
 
   /* Copy the result of the function into register P3 */
@@ -67177,12 +67294,12 @@ case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */
       ** then the result is always NULL.
       ** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
       */
-      if( pOp->p5 & SQLITE_STOREP2 ){
+      if( pOp->p5 & SQLITE_JUMPIFNULL ){
+        pc = pOp->p2-1;
+      }else if( pOp->p5 & SQLITE_STOREP2 ){
         pOut = &aMem[pOp->p2];
         MemSetTypeFlag(pOut, MEM_Null);
         REGISTER_TRACE(pOp->p2, pOut);
-      }else if( pOp->p5 & SQLITE_JUMPIFNULL ){
-        pc = pOp->p2-1;
       }
       break;
     }
@@ -68038,9 +68155,10 @@ case OP_Savepoint: {
   assert( u.as.p1==SAVEPOINT_BEGIN||u.as.p1==SAVEPOINT_RELEASE||u.as.p1==SAVEPOINT_ROLLBACK );
   assert( db->pSavepoint || db->isTransactionSavepoint==0 );
   assert( checkSavepointCount(db) );
+  assert( p->bIsReader );
 
   if( u.as.p1==SAVEPOINT_BEGIN ){
-    if( db->writeVdbeCnt>0 ){
+    if( db->nVdbeWrite>0 ){
       /* A new savepoint cannot be created if there are active write
       ** statements (i.e. open read/write incremental blob handles).
       */
@@ -68080,6 +68198,7 @@ case OP_Savepoint: {
         u.as.pNew->pNext = db->pSavepoint;
         db->pSavepoint = u.as.pNew;
         u.as.pNew->nDeferredCons = db->nDeferredCons;
+        u.as.pNew->nDeferredImmCons = db->nDeferredImmCons;
       }
     }
   }else{
@@ -68097,7 +68216,7 @@ case OP_Savepoint: {
     if( !u.as.pSavepoint ){
       sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", u.as.zName);
       rc = SQLITE_ERROR;
-    }else if( db->writeVdbeCnt>0 && u.as.p1==SAVEPOINT_RELEASE ){
+    }else if( db->nVdbeWrite>0 && u.as.p1==SAVEPOINT_RELEASE ){
       /* It is not possible to release (commit) a savepoint if there are
       ** active write statements.
       */
@@ -68167,6 +68286,7 @@ case OP_Savepoint: {
         }
       }else{
         db->nDeferredCons = u.as.pSavepoint->nDeferredCons;
+        db->nDeferredImmCons = u.as.pSavepoint->nDeferredImmCons;
       }
 
       if( !isTransaction ){
@@ -68200,10 +68320,11 @@ case OP_AutoCommit: {
   u.at.turnOnAC = u.at.desiredAutoCommit && !db->autoCommit;
   assert( u.at.desiredAutoCommit==1 || u.at.desiredAutoCommit==0 );
   assert( u.at.desiredAutoCommit==1 || u.at.iRollback==0 );
-  assert( db->activeVdbeCnt>0 );  /* At least this one VM is active */
+  assert( db->nVdbeActive>0 );  /* At least this one VM is active */
+  assert( p->bIsReader );
 
 #if 0
-  if( u.at.turnOnAC && u.at.iRollback && db->activeVdbeCnt>1 ){
+  if( u.at.turnOnAC && u.at.iRollback && db->nVdbeActive>1 ){
     /* If this instruction implements a ROLLBACK and other VMs are
     ** still running, and a transaction is active, return an error indicating
     ** that the other VMs must complete first.
@@ -68213,7 +68334,7 @@ case OP_AutoCommit: {
     rc = SQLITE_BUSY;
   }else
 #endif
-  if( u.at.turnOnAC && !u.at.iRollback && db->writeVdbeCnt>0 ){
+  if( u.at.turnOnAC && !u.at.iRollback && db->nVdbeWrite>0 ){
     /* If this instruction implements a COMMIT and other VMs are writing
     ** return an error indicating that the other VMs must complete first.
     */
@@ -68271,8 +68392,8 @@ case OP_AutoCommit: {
 ** other process can start another write transaction while this transaction is
 ** underway.  Starting a write transaction also creates a rollback journal. A
 ** write transaction must be started before any changes can be made to the
-** database.  If P2 is 2 or greater then an EXCLUSIVE lock is also obtained
-** on the file.
+** database.  If P2 is greater than or equal to 2 then an EXCLUSIVE lock is
+** also obtained on the file.
 **
 ** If a write-transaction is started and the Vdbe.usesStmtJournal flag is
 ** true (this flag is set if the Vdbe may modify more than one row and may
@@ -68291,8 +68412,14 @@ case OP_Transaction: {
   Btree *pBt;
 #endif /* local variables moved into u.au */
 
+  assert( p->bIsReader );
+  assert( p->readOnly==0 || pOp->p2==0 );
   assert( pOp->p1>=0 && pOp->p1<db->nDb );
   assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
+  if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){
+    rc = SQLITE_READONLY;
+    goto abort_due_to_error;
+  }
   u.au.pBt = db->aDb[pOp->p1].pBt;
 
   if( u.au.pBt ){
@@ -68307,7 +68434,7 @@ case OP_Transaction: {
     }
 
     if( pOp->p2 && p->usesStmtJournal
-     && (db->autoCommit==0 || db->activeVdbeCnt>1)
+     && (db->autoCommit==0 || db->nVdbeRead>1)
     ){
       assert( sqlite3BtreeIsInTrans(u.au.pBt) );
       if( p->iStatement==0 ){
@@ -68325,6 +68452,7 @@ case OP_Transaction: {
       ** counter. If the statement transaction needs to be rolled back,
       ** the value of this counter needs to be restored too.  */
       p->nStmtDefCons = db->nDeferredCons;
+      p->nStmtDefImmCons = db->nDeferredImmCons;
     }
   }
   break;
@@ -68349,6 +68477,7 @@ case OP_ReadCookie: {               /* out2-prerelease */
   int iCookie;
 #endif /* local variables moved into u.av */
 
+  assert( p->bIsReader );
   u.av.iDb = pOp->p1;
   u.av.iCookie = pOp->p3;
   assert( pOp->p3<SQLITE_N_BTREE_META );
@@ -68378,6 +68507,7 @@ case OP_SetCookie: {       /* in3 */
   assert( pOp->p2<SQLITE_N_BTREE_META );
   assert( pOp->p1>=0 && pOp->p1<db->nDb );
   assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
+  assert( p->readOnly==0 );
   u.aw.pDb = &db->aDb[pOp->p1];
   assert( u.aw.pDb->pBt!=0 );
   assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) );
@@ -68430,6 +68560,7 @@ case OP_VerifyCookie: {
   assert( pOp->p1>=0 && pOp->p1<db->nDb );
   assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
   assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) );
+  assert( p->bIsReader );
   u.ax.pBt = db->aDb[pOp->p1].pBt;
   if( u.ax.pBt ){
     sqlite3BtreeGetMeta(u.ax.pBt, BTREE_SCHEMA_VERSION, (u32 *)&u.ax.iMeta);
@@ -68527,6 +68658,8 @@ case OP_OpenWrite: {
 
   assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 );
   assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 );
+  assert( p->bIsReader );
+  assert( pOp->opcode==OP_OpenRead || p->readOnly==0 );
 
   if( p->expired ){
     rc = SQLITE_ABORT;
@@ -69721,7 +69854,7 @@ case OP_Rowid: {                 /* out2-prerelease */
     u.bn.pModule = u.bn.pVtab->pModule;
     assert( u.bn.pModule->xRowid );
     rc = u.bn.pModule->xRowid(u.bn.pC->pVtabCursor, &u.bn.v);
-    importVtabErrMsg(p, u.bn.pVtab);
+    sqlite3VtabImportErrmsg(p, u.bn.pVtab);
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
   }else{
     assert( u.bn.pC->pCursor!=0 );
@@ -69813,7 +69946,7 @@ case OP_Sort: {        /* jump */
   sqlite3_sort_count++;
   sqlite3_search_count--;
 #endif
-  p->aCounter[SQLITE_STMTSTATUS_SORT-1]++;
+  p->aCounter[SQLITE_STMTSTATUS_SORT]++;
   /* Fall through into OP_Rewind */
 }
 /* Opcode: Rewind P1 P2 * * *
@@ -69895,9 +70028,8 @@ case OP_Next: {        /* jump */
   int res;
 #endif /* local variables moved into u.br */
 
-  CHECK_FOR_INTERRUPT;
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
-  assert( pOp->p5<=ArraySize(p->aCounter) );
+  assert( pOp->p5<ArraySize(p->aCounter) );
   u.br.pC = p->apCsr[pOp->p1];
   if( u.br.pC==0 ){
     break;  /* See ticket #2273 */
@@ -69907,7 +70039,7 @@ case OP_Next: {        /* jump */
     assert( pOp->opcode==OP_SorterNext );
     rc = sqlite3VdbeSorterNext(db, u.br.pC, &u.br.res);
   }else{
-    u.br.res = 1;
+    /* u.br.res = 1; // Always initialized by the xAdvance() call */
     assert( u.br.pC->deferredMoveto==0 );
     assert( u.br.pC->pCursor );
     assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext );
@@ -69918,13 +70050,13 @@ case OP_Next: {        /* jump */
   u.br.pC->cacheStatus = CACHE_STALE;
   if( u.br.res==0 ){
     pc = pOp->p2 - 1;
-    if( pOp->p5 ) p->aCounter[pOp->p5-1]++;
+    p->aCounter[pOp->p5]++;
 #ifdef SQLITE_TEST
     sqlite3_search_count++;
 #endif
   }
   u.br.pC->rowidIsValid = 0;
-  break;
+  goto check_for_interrupt;
 }
 
 /* Opcode: IdxInsert P1 P2 P3 * P5
@@ -70145,15 +70277,18 @@ case OP_Destroy: {     /* out2-prerelease */
   int iDb;
 #endif /* local variables moved into u.bw */
 
+  assert( p->readOnly==0 );
 #ifndef SQLITE_OMIT_VIRTUALTABLE
   u.bw.iCnt = 0;
   for(u.bw.pVdbe=db->pVdbe; u.bw.pVdbe; u.bw.pVdbe = u.bw.pVdbe->pNext){
-    if( u.bw.pVdbe->magic==VDBE_MAGIC_RUN && u.bw.pVdbe->inVtabMethod<2 && u.bw.pVdbe->pc>=0 ){
+    if( u.bw.pVdbe->magic==VDBE_MAGIC_RUN && u.bw.pVdbe->bIsReader
+     && u.bw.pVdbe->inVtabMethod<2 && u.bw.pVdbe->pc>=0
+    ){
       u.bw.iCnt++;
     }
   }
 #else
-  u.bw.iCnt = db->activeVdbeCnt;
+  u.bw.iCnt = db->nVdbeRead;
 #endif
   pOut->flags = MEM_Null;
   if( u.bw.iCnt>1 ){
@@ -70202,6 +70337,7 @@ case OP_Clear: {
 #endif /* local variables moved into u.bx */
 
   u.bx.nChange = 0;
+  assert( p->readOnly==0 );
   assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 );
   rc = sqlite3BtreeClearTable(
       db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bx.nChange : 0)
@@ -70250,6 +70386,7 @@ case OP_CreateTable: {          /* out2-prerelease */
   u.by.pgno = 0;
   assert( pOp->p1>=0 && pOp->p1<db->nDb );
   assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
+  assert( p->readOnly==0 );
   u.by.pDb = &db->aDb[pOp->p1];
   assert( u.by.pDb->pBt!=0 );
   if( pOp->opcode==OP_CreateTable ){
@@ -70402,6 +70539,7 @@ case OP_IntegrityCk: {
   Mem *pnErr;     /* Register keeping track of errors remaining */
 #endif /* local variables moved into u.ca */
 
+  assert( p->bIsReader );
   u.ca.nRoot = pOp->p2;
   assert( u.ca.nRoot>0 );
   u.ca.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.ca.nRoot+1) );
@@ -70464,7 +70602,7 @@ case OP_RowSetRead: {       /* jump, in1, out3 */
 #if 0  /* local variables moved into u.cb */
   i64 val;
 #endif /* local variables moved into u.cb */
-  CHECK_FOR_INTERRUPT;
+
   pIn1 = &aMem[pOp->p1];
   if( (pIn1->flags & MEM_RowSet)==0
    || sqlite3RowSetNext(pIn1->u.pRowSet, &u.cb.val)==0
@@ -70476,7 +70614,7 @@ case OP_RowSetRead: {       /* jump, in1, out3 */
     /* A value was pulled from the index */
     sqlite3VdbeMemSetInt64(&aMem[pOp->p3], u.cb.val);
   }
-  break;
+  goto check_for_interrupt;
 }
 
 /* Opcode: RowSetTest P1 P2 P3 P4
@@ -70696,7 +70834,9 @@ case OP_Param: {           /* out2-prerelease */
 ** statement counter is incremented (immediate foreign key constraints).
 */
 case OP_FkCounter: {
-  if( pOp->p1 ){
+  if( db->flags & SQLITE_DeferFKs ){
+    db->nDeferredImmCons += pOp->p2;
+  }else if( pOp->p1 ){
     db->nDeferredCons += pOp->p2;
   }else{
     p->nFkConstraint += pOp->p2;
@@ -70717,9 +70857,9 @@ case OP_FkCounter: {
 */
 case OP_FkIfZero: {         /* jump */
   if( pOp->p1 ){
-    if( db->nDeferredCons==0 ) pc = pOp->p2-1;
+    if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1;
   }else{
-    if( p->nFkConstraint==0 ) pc = pOp->p2-1;
+    if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1;
   }
   break;
 }
@@ -70923,6 +71063,7 @@ case OP_Checkpoint: {
   Mem *pMem;                      /* Write results here */
 #endif /* local variables moved into u.ci */
 
+  assert( p->readOnly==0 );
   u.ci.aRes[0] = 0;
   u.ci.aRes[1] = u.ci.aRes[2] = -1;
   assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE
@@ -70974,6 +71115,7 @@ case OP_JournalMode: {    /* out2-prerelease */
        || u.cj.eNew==PAGER_JOURNALMODE_QUERY
   );
   assert( pOp->p1>=0 && pOp->p1<db->nDb );
+  assert( p->readOnly==0 );
 
   u.cj.pBt = db->aDb[pOp->p1].pBt;
   u.cj.pPager = sqlite3BtreePager(u.cj.pBt);
@@ -70997,7 +71139,7 @@ case OP_JournalMode: {    /* out2-prerelease */
   if( (u.cj.eNew!=u.cj.eOld)
    && (u.cj.eOld==PAGER_JOURNALMODE_WAL || u.cj.eNew==PAGER_JOURNALMODE_WAL)
   ){
-    if( !db->autoCommit || db->activeVdbeCnt>1 ){
+    if( !db->autoCommit || db->nVdbeRead>1 ){
       rc = SQLITE_ERROR;
       sqlite3SetString(&p->zErrMsg, db,
           "cannot change %s wal mode from within a transaction",
@@ -71056,6 +71198,7 @@ case OP_JournalMode: {    /* out2-prerelease */
 ** a transaction.
 */
 case OP_Vacuum: {
+  assert( p->readOnly==0 );
   rc = sqlite3RunVacuum(&p->zErrMsg, db);
   break;
 }
@@ -71075,6 +71218,7 @@ case OP_IncrVacuum: {        /* jump */
 
   assert( pOp->p1>=0 && pOp->p1<db->nDb );
   assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
+  assert( p->readOnly==0 );
   u.ck.pBt = db->aDb[pOp->p1].pBt;
   rc = sqlite3BtreeIncrVacuum(u.ck.pBt);
   if( rc==SQLITE_DONE ){
@@ -71151,7 +71295,7 @@ case OP_VBegin: {
 #endif /* local variables moved into u.cl */
   u.cl.pVTab = pOp->p4.pVtab;
   rc = sqlite3VtabBegin(db, u.cl.pVTab);
-  if( u.cl.pVTab ) importVtabErrMsg(p, u.cl.pVTab->pVtab);
+  if( u.cl.pVTab ) sqlite3VtabImportErrmsg(p, u.cl.pVTab->pVtab);
   break;
 }
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -71197,13 +71341,14 @@ case OP_VOpen: {
   sqlite3_module *pModule;
 #endif /* local variables moved into u.cm */
 
+  assert( p->bIsReader );
   u.cm.pCur = 0;
   u.cm.pVtabCursor = 0;
   u.cm.pVtab = pOp->p4.pVtab->pVtab;
   u.cm.pModule = (sqlite3_module *)u.cm.pVtab->pModule;
   assert(u.cm.pVtab && u.cm.pModule);
   rc = u.cm.pModule->xOpen(u.cm.pVtab, &u.cm.pVtabCursor);
-  importVtabErrMsg(p, u.cm.pVtab);
+  sqlite3VtabImportErrmsg(p, u.cm.pVtab);
   if( SQLITE_OK==rc ){
     /* Initialize sqlite3_vtab_cursor base class */
     u.cm.pVtabCursor->pVtab = u.cm.pVtab;
@@ -71283,7 +71428,7 @@ case OP_VFilter: {   /* jump */
     p->inVtabMethod = 1;
     rc = u.cn.pModule->xFilter(u.cn.pVtabCursor, u.cn.iQuery, pOp->p4.z, u.cn.nArg, u.cn.apArg);
     p->inVtabMethod = 0;
-    importVtabErrMsg(p, u.cn.pVtab);
+    sqlite3VtabImportErrmsg(p, u.cn.pVtab);
     if( rc==SQLITE_OK ){
       u.cn.res = u.cn.pModule->xEof(u.cn.pVtabCursor);
     }
@@ -71336,7 +71481,7 @@ case OP_VColumn: {
   MemSetTypeFlag(&u.co.sContext.s, MEM_Null);
 
   rc = u.co.pModule->xColumn(pCur->pVtabCursor, &u.co.sContext, pOp->p2);
-  importVtabErrMsg(p, u.co.pVtab);
+  sqlite3VtabImportErrmsg(p, u.co.pVtab);
   if( u.co.sContext.isError ){
     rc = u.co.sContext.isError;
   }
@@ -71391,7 +71536,7 @@ case OP_VNext: {   /* jump */
   p->inVtabMethod = 1;
   rc = u.cp.pModule->xNext(u.cp.pCur->pVtabCursor);
   p->inVtabMethod = 0;
-  importVtabErrMsg(p, u.cp.pVtab);
+  sqlite3VtabImportErrmsg(p, u.cp.pVtab);
   if( rc==SQLITE_OK ){
     u.cp.res = u.cp.pModule->xEof(u.cp.pCur->pVtabCursor);
   }
@@ -71400,7 +71545,7 @@ case OP_VNext: {   /* jump */
     /* If there is data, jump to P2 */
     pc = pOp->p2 - 1;
   }
-  break;
+  goto check_for_interrupt;
 }
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
 
@@ -71421,6 +71566,7 @@ case OP_VRename: {
   u.cq.pName = &aMem[pOp->p1];
   assert( u.cq.pVtab->pModule->xRename );
   assert( memIsValid(u.cq.pName) );
+  assert( p->readOnly==0 );
   REGISTER_TRACE(pOp->p1, u.cq.pName);
   assert( u.cq.pName->flags & MEM_Str );
   testcase( u.cq.pName->enc==SQLITE_UTF8 );
@@ -71429,7 +71575,7 @@ case OP_VRename: {
   rc = sqlite3VdbeChangeEncoding(u.cq.pName, SQLITE_UTF8);
   if( rc==SQLITE_OK ){
     rc = u.cq.pVtab->pModule->xRename(u.cq.pVtab, u.cq.pName->z);
-    importVtabErrMsg(p, u.cq.pVtab);
+    sqlite3VtabImportErrmsg(p, u.cq.pVtab);
     p->expired = 0;
   }
   break;
@@ -71474,6 +71620,7 @@ case OP_VUpdate: {
   assert( pOp->p2==1        || pOp->p5==OE_Fail   || pOp->p5==OE_Rollback
        || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace
   );
+  assert( p->readOnly==0 );
   u.cr.pVtab = pOp->p4.pVtab->pVtab;
   u.cr.pModule = (sqlite3_module *)u.cr.pVtab->pModule;
   u.cr.nArg = pOp->p2;
@@ -71492,7 +71639,7 @@ case OP_VUpdate: {
     db->vtabOnConflict = pOp->p5;
     rc = u.cr.pModule->xUpdate(u.cr.pVtab, u.cr.nArg, u.cr.apArg, &u.cr.rowid);
     db->vtabOnConflict = vtabOnConflict;
-    importVtabErrMsg(p, u.cr.pVtab);
+    sqlite3VtabImportErrmsg(p, u.cr.pVtab);
     if( rc==SQLITE_OK && pOp->p1 ){
       assert( u.cr.nArg>1 && u.cr.apArg[0] && (u.cr.apArg[0]->flags&MEM_Null) );
       db->lastRowid = lastRowid = u.cr.rowid;
@@ -71659,6 +71806,8 @@ vdbe_error_halt:
   ** top. */
 vdbe_return:
   db->lastRowid = lastRowid;
+  testcase( nVmStep>0 );
+  p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep;
   sqlite3VdbeLeave(p);
   return rc;
 
@@ -72226,7 +72375,7 @@ typedef struct FileWriter FileWriter;
 ** other key value. If the keys are equal (only possible with two EOF
 ** values), it doesn't matter which index is stored.
 **
-** The (N/4) elements of aTree[] that preceed the final (N/2) described 
+** 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 
 ** currently points to the smallest key value. aTree[0] is unused.
@@ -73501,12 +73650,6 @@ typedef struct FileChunk FileChunk;
 */
 #define JOURNAL_CHUNKSIZE ((int)(1024-sizeof(FileChunk*)))
 
-/* Macro to find the minimum of two numeric values.
-*/
-#ifndef MIN
-# define MIN(x,y) ((x)<(y)?(x):(y))
-#endif
-
 /*
 ** The rollback journal is composed of a linked list of these structures.
 */
@@ -73943,7 +74086,7 @@ static void incrAggFunctionDepth(Expr *pExpr, int N){
 ** column reference is so that the column reference will be recognized as
 ** usable by indices within the WHERE clause processing logic. 
 **
-** Hack:  The TK_AS operator is inhibited if zType[0]=='G'.  This means
+** The TK_AS operator is inhibited if zType[0]=='G'.  This means
 ** that in a GROUP BY clause, the expression is evaluated twice.  Hence:
 **
 **     SELECT random()%5 AS x, count(*) FROM tab GROUP BY x
@@ -73953,8 +74096,9 @@ static void incrAggFunctionDepth(Expr *pExpr, int N){
 **     SELECT random()%5 AS x, count(*) FROM tab GROUP BY random()%5
 **
 ** The result of random()%5 in the GROUP BY clause is probably different
-** from the result in the result-set.  We might fix this someday.  Or
-** then again, we might not...
+** from the result in the result-set.  On the other hand Standard SQL does
+** not allow the GROUP BY clause to contain references to result-set columns.
+** So this should never come up in well-formed queries.
 **
 ** If the reference is followed by a COLLATE operator, then make sure
 ** the COLLATE operator is preserved.  For example:
@@ -74128,11 +74272,20 @@ static int lookupName(
   ** resulting in an appropriate error message toward the end of this routine
   */
   if( zDb ){
-    for(i=0; i<db->nDb; i++){
-      assert( db->aDb[i].zName );
-      if( sqlite3StrICmp(db->aDb[i].zName,zDb)==0 ){
-        pSchema = db->aDb[i].pSchema;
-        break;
+    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. */
+      zDb = 0;
+    }else{
+      for(i=0; i<db->nDb; i++){
+        assert( db->aDb[i].zName );
+        if( sqlite3StrICmp(db->aDb[i].zName,zDb)==0 ){
+          pSchema = db->aDb[i].pSchema;
+          break;
+        }
       }
     }
   }
@@ -74275,10 +74428,16 @@ static int lookupName(
     ** forms the result set entry ("a+b" in the example) and return immediately.
     ** Note that the expression in the result set should have already been
     ** resolved by the time the WHERE clause is resolved.
+    **
+    ** The ability to use an output result-set column in the WHERE, GROUP BY,
+    ** or HAVING clauses, or as part of a larger expression in the ORDRE BY
+    ** clause is not standard SQL.  This is a (goofy) SQLite extension, that
+    ** is supported for backwards compatibility only.  TO DO: Issue a warning
+    ** on sqlite3_log() whenever the capability is used.
     */
     if( (pEList = pNC->pEList)!=0
      && zTab==0
-     && ((pNC->ncFlags & NC_AsMaybe)==0 || cnt==0)
+     && cnt==0
     ){
       for(j=0; j<pEList->nExpr; j++){
         char *zAs = pEList->a[j].zName;
@@ -74411,6 +74570,39 @@ SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSr
 }
 
 /*
+** Report an error that an expression is not valid for a partial index WHERE
+** clause.
+*/
+static void notValidPartIdxWhere(
+  Parse *pParse,       /* Leave error message here */
+  NameContext *pNC,    /* The name context */
+  const char *zMsg     /* Type of error */
+){
+  if( (pNC->ncFlags & NC_PartIdx)!=0 ){
+    sqlite3ErrorMsg(pParse, "%s prohibited in partial index WHERE clauses",
+                    zMsg);
+  }
+}
+
+#ifndef SQLITE_OMIT_CHECK
+/*
+** Report an error that an expression is not valid for a CHECK constraint.
+*/
+static void notValidCheckConstraint(
+  Parse *pParse,       /* Leave error message here */
+  NameContext *pNC,    /* The name context */
+  const char *zMsg     /* Type of error */
+){
+  if( (pNC->ncFlags & NC_IsCheck)!=0 ){
+    sqlite3ErrorMsg(pParse,"%s prohibited in CHECK constraints", zMsg);
+  }
+}
+#else
+# define notValidCheckConstraint(P,N,M)
+#endif
+
+
+/*
 ** This routine is callback for sqlite3WalkExpr().
 **
 ** Resolve symbolic names into TK_COLUMN operators for the current
@@ -74509,6 +74701,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
 
       testcase( pExpr->op==TK_CONST_FUNC );
       assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
+      notValidPartIdxWhere(pParse, pNC, "functions");
       zId = pExpr->u.zToken;
       nId = sqlite3Strlen30(zId);
       pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
@@ -74574,11 +74767,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
       testcase( pExpr->op==TK_IN );
       if( ExprHasProperty(pExpr, EP_xIsSelect) ){
         int nRef = pNC->nRef;
-#ifndef SQLITE_OMIT_CHECK
-        if( (pNC->ncFlags & NC_IsCheck)!=0 ){
-          sqlite3ErrorMsg(pParse,"subqueries prohibited in CHECK constraints");
-        }
-#endif
+        notValidCheckConstraint(pParse, pNC, "subqueries");
+        notValidPartIdxWhere(pParse, pNC, "subqueries");
         sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
         assert( pNC->nRef>=nRef );
         if( nRef!=pNC->nRef ){
@@ -74587,14 +74777,11 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
       }
       break;
     }
-#ifndef SQLITE_OMIT_CHECK
     case TK_VARIABLE: {
-      if( (pNC->ncFlags & NC_IsCheck)!=0 ){
-        sqlite3ErrorMsg(pParse,"parameters prohibited in CHECK constraints");
-      }
+      notValidCheckConstraint(pParse, pNC, "parameters");
+      notValidPartIdxWhere(pParse, pNC, "parameters");
       break;
     }
-#endif
   }
   return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue;
 }
@@ -74685,7 +74872,7 @@ static int resolveOrderByTermToExprList(
   ** result-set entry.
   */
   for(i=0; i<pEList->nExpr; i++){
-    if( sqlite3ExprCompare(pEList->a[i].pExpr, pE)<2 ){
+    if( sqlite3ExprCompare(pEList->a[i].pExpr, pE, -1)<2 ){
       return i+1;
     }
   }
@@ -74812,7 +74999,7 @@ static int resolveCompoundOrderBy(
 /*
 ** Check every term in the ORDER BY or GROUP BY clause pOrderBy of
 ** the SELECT statement pSelect.  If any term is reference to a
-** result set expression (as determined by the ExprList.a.iCol field)
+** result set expression (as determined by the ExprList.a.iOrderByCol field)
 ** then convert that term into a copy of the corresponding result set
 ** column.
 **
@@ -74860,7 +75047,7 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(
 ** If the order-by term is an integer I between 1 and N (where N is the
 ** number of columns in the result set of the SELECT) then the expression
 ** in the resolution is a copy of the I-th result-set expression.  If
-** the order-by term is an identify that corresponds to the AS-name of
+** the order-by term is an identifier that corresponds to the AS-name of
 ** a result-set expression, then the term resolves to a copy of the
 ** result-set expression.  Otherwise, the expression is resolved in
 ** the usual way - using sqlite3ResolveExprNames().
@@ -74886,16 +75073,19 @@ static int resolveOrderGroupBy(
   pParse = pNC->pParse;
   for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
     Expr *pE = pItem->pExpr;
-    iCol = resolveAsName(pParse, pSelect->pEList, pE);
-    if( iCol>0 ){
-      /* If an AS-name match is found, mark this ORDER BY column as being
-      ** a copy of the iCol-th result-set column.  The subsequent call to
-      ** sqlite3ResolveOrderGroupBy() will convert the expression to a
-      ** copy of the iCol-th result-set expression. */
-      pItem->iOrderByCol = (u16)iCol;
-      continue;
+    Expr *pE2 = sqlite3ExprSkipCollate(pE);
+    if( zType[0]!='G' ){
+      iCol = resolveAsName(pParse, pSelect->pEList, pE2);
+      if( iCol>0 ){
+        /* If an AS-name match is found, mark this ORDER BY column as being
+        ** a copy of the iCol-th result-set column.  The subsequent call to
+        ** sqlite3ResolveOrderGroupBy() will convert the expression to a
+        ** copy of the iCol-th result-set expression. */
+        pItem->iOrderByCol = (u16)iCol;
+        continue;
+      }
     }
-    if( sqlite3ExprIsInteger(sqlite3ExprSkipCollate(pE), &iCol) ){
+    if( sqlite3ExprIsInteger(pE2, &iCol) ){
       /* The ORDER BY term is an integer constant.  Again, set the column
       ** number so that sqlite3ResolveOrderGroupBy() will convert the
       ** order-by term to a copy of the result-set expression */
@@ -74913,7 +75103,7 @@ static int resolveOrderGroupBy(
       return 1;
     }
     for(j=0; j<pSelect->pEList->nExpr; j++){
-      if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr)==0 ){
+      if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
         pItem->iOrderByCol = j+1;
       }
     }
@@ -75038,7 +75228,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
       return WRC_Abort;
     }
   
-    /* Add the expression list to the name-context before parsing the
+    /* Add the output column list to the name-context before parsing the
     ** other expressions in the SELECT statement. This is so that
     ** expressions in the WHERE clause (etc.) can refer to expressions by
     ** aliases in the result set.
@@ -75047,10 +75237,8 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
     ** re-evaluated for each reference to it.
     */
     sNC.pEList = p->pEList;
-    sNC.ncFlags |= NC_AsMaybe;
     if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort;
     if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort;
-    sNC.ncFlags &= ~NC_AsMaybe;
 
     /* The ORDER BY and GROUP BY clauses may not refer to terms in
     ** outer queries 
@@ -75220,6 +75408,48 @@ SQLITE_PRIVATE void sqlite3ResolveSelectNames(
   sqlite3WalkSelect(&w, p);
 }
 
+/*
+** Resolve names in expressions that can only reference a single table:
+**
+**    *   CHECK constraints
+**    *   WHERE clauses on partial indices
+**
+** The Expr.iTable value for Expr.op==TK_COLUMN nodes of the expression
+** is set to -1 and the Expr.iColumn value is set to the column number.
+**
+** Any errors cause an error message to be set in pParse.
+*/
+SQLITE_PRIVATE void sqlite3ResolveSelfReference(
+  Parse *pParse,      /* Parsing context */
+  Table *pTab,        /* The table being referenced */
+  int type,           /* NC_IsCheck or NC_PartIdx */
+  Expr *pExpr,        /* Expression to resolve.  May be NULL. */
+  ExprList *pList     /* Expression list to resolve.  May be NUL. */
+){
+  SrcList sSrc;                   /* Fake SrcList for pParse->pNewTable */
+  NameContext sNC;                /* Name context for pParse->pNewTable */
+  int i;                          /* Loop counter */
+
+  assert( type==NC_IsCheck || type==NC_PartIdx );
+  memset(&sNC, 0, sizeof(sNC));
+  memset(&sSrc, 0, sizeof(sSrc));
+  sSrc.nSrc = 1;
+  sSrc.a[0].zName = pTab->zName;
+  sSrc.a[0].pTab = pTab;
+  sSrc.a[0].iCursor = -1;
+  sNC.pParse = pParse;
+  sNC.pSrcList = &sSrc;
+  sNC.ncFlags = type;
+  if( sqlite3ResolveExprNames(&sNC, pExpr) ) return;
+  if( pList ){
+    for(i=0; i<pList->nExpr; i++){
+      if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){
+        return;
+      }
+    }
+  }
+}
+
 /************** End of resolve.c *********************************************/
 /************** Begin file expr.c ********************************************/
 /*
@@ -75337,8 +75567,7 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
       p = p->pLeft;
       continue;
     }
-    assert( op!=TK_REGISTER || p->op2!=TK_COLLATE );
-    if( op==TK_COLLATE ){
+    if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){
       pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
       break;
     }
@@ -76143,6 +76372,7 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags)
     pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan);
     pItem->sortOrder = pOldItem->sortOrder;
     pItem->done = 0;
+    pItem->bSpanIsTab = pOldItem->bSpanIsTab;
     pItem->iOrderByCol = pOldItem->iOrderByCol;
     pItem->iAlias = pOldItem->iAlias;
   }
@@ -76501,6 +76731,7 @@ SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){
     case TK_UMINUS: {
       int v;
       if( sqlite3ExprIsInteger(p->pLeft, &v) ){
+        assert( v!=-2147483648 );
         *pValue = -v;
         rc = 1;
       }
@@ -76819,15 +77050,15 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
     /* Could not found an existing table or index to use as the RHS b-tree.
     ** We will have to generate an ephemeral table to do the job.
     */
-    double savedNQueryLoop = pParse->nQueryLoop;
+    u32 savedNQueryLoop = pParse->nQueryLoop;
     int rMayHaveNull = 0;
     eType = IN_INDEX_EPH;
     if( prNotFound ){
       *prNotFound = rMayHaveNull = ++pParse->nMem;
       sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound);
     }else{
-      testcase( pParse->nQueryLoop>(double)1 );
-      pParse->nQueryLoop = (double)1;
+      testcase( pParse->nQueryLoop>0 );
+      pParse->nQueryLoop = 0;
       if( pX->pLeft->iColumn<0 && !ExprHasAnyProperty(pX, EP_xIsSelect) ){
         eType = IN_INDEX_ROWID;
       }
@@ -76869,7 +77100,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
 **
 ** If rMayHaveNull is zero, that means that the subquery is being used
 ** for membership testing only.  There is no need to initialize any
-** registers to indicate the presense or absence of NULLs on the RHS.
+** registers to indicate the presence or absence of NULLs on the RHS.
 **
 ** For a SELECT or EXISTS operator, return the register that holds the
 ** result.  For IN operators or if an error occurs, the return value is 0.
@@ -76914,10 +77145,9 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
   switch( pExpr->op ){
     case TK_IN: {
       char affinity;              /* Affinity of the LHS of the IN */
-      KeyInfo keyInfo;            /* Keyinfo for the generated table */
-      static u8 sortOrder = 0;    /* Fake aSortOrder for keyInfo */
       int addr;                   /* Address of OP_OpenEphemeral instruction */
       Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */
+      KeyInfo *pKeyInfo = 0;      /* Key information */
 
       if( rMayHaveNull ){
         sqlite3VdbeAddOp2(v, OP_Null, 0, rMayHaveNull);
@@ -76941,9 +77171,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
       pExpr->iTable = pParse->nTab++;
       addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid);
       if( rMayHaveNull==0 ) sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
-      memset(&keyInfo, 0, sizeof(keyInfo));
-      keyInfo.nField = 1;
-      keyInfo.aSortOrder = &sortOrder;
+      pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, 1);
 
       if( ExprHasProperty(pExpr, EP_xIsSelect) ){
         /* Case 1:     expr IN (SELECT ...)
@@ -76959,14 +77187,17 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
         dest.affSdst = (u8)affinity;
         assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
         pExpr->x.pSelect->iLimit = 0;
+        testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
         if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){
+          sqlite3DbFree(pParse->db, pKeyInfo);
           return 0;
         }
         pEList = pExpr->x.pSelect->pEList;
-        if( ALWAYS(pEList!=0 && pEList->nExpr>0) ){ 
-          keyInfo.aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
-              pEList->a[0].pExpr);
-        }
+        assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
+        assert( pEList!=0 );
+        assert( pEList->nExpr>0 );
+        pKeyInfo->aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
+                                                         pEList->a[0].pExpr);
       }else if( ALWAYS(pExpr->x.pList!=0) ){
         /* Case 2:     expr IN (exprlist)
         **
@@ -76983,8 +77214,9 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
         if( !affinity ){
           affinity = SQLITE_AFF_NONE;
         }
-        keyInfo.aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
-        keyInfo.aSortOrder = &sortOrder;
+        if( pKeyInfo ){
+          pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
+        }
 
         /* Loop through each expression in <exprlist>. */
         r1 = sqlite3GetTempReg(pParse);
@@ -77023,8 +77255,8 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
         sqlite3ReleaseTempReg(pParse, r1);
         sqlite3ReleaseTempReg(pParse, r2);
       }
-      if( !isRowid ){
-        sqlite3VdbeChangeP4(v, addr, (void *)&keyInfo, P4_KEYINFO);
+      if( pKeyInfo ){
+        sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO_HANDOFF);
       }
       break;
     }
@@ -77584,15 +77816,20 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
       /* Otherwise, fall thru into the TK_COLUMN case */
     }
     case TK_COLUMN: {
-      if( pExpr->iTable<0 ){
-        /* This only happens when coding check constraints */
-        assert( pParse->ckBase>0 );
-        inReg = pExpr->iColumn + pParse->ckBase;
-      }else{
-        inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
-                                 pExpr->iColumn, pExpr->iTable, target,
-                                 pExpr->op2);
+      int iTab = pExpr->iTable;
+      if( iTab<0 ){
+        if( pParse->ckBase>0 ){
+          /* Generating CHECK constraints or inserting into partial index */
+          inReg = pExpr->iColumn + pParse->ckBase;
+          break;
+        }else{
+          /* Deleting from a partial index */
+          iTab = pParse->iPartIdxTab;
+        }
       }
+      inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
+                               pExpr->iColumn, iTab, target,
+                               pExpr->op2);
       break;
     }
     case TK_INTEGER: {
@@ -78720,6 +78957,7 @@ static void exprCodeBetween(
   compRight.pLeft = &exprX;
   compRight.pRight = pExpr->x.pList->a[1].pExpr;
   exprX.iTable = sqlite3ExprCodeTemp(pParse, &exprX, &regFree1);
+  exprX.op2 = exprX.op;
   exprX.op = TK_REGISTER;
   if( jumpIfTrue ){
     sqlite3ExprIfTrue(pParse, &exprAnd, dest, jumpIfNull);
@@ -79015,6 +79253,12 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
 ** by a COLLATE operator at the top level.  Return 2 if there are differences
 ** other than the top-level COLLATE operator.
 **
+** If any subelement of pB has Expr.iTable==(-1) then it is allowed
+** to compare equal to an equivalent element in pA with Expr.iTable==iTab.
+**
+** The pA side might be using TK_REGISTER.  If that is the case and pB is
+** not using TK_REGISTER but is otherwise equivalent, then still return 0.
+**
 ** Sometimes this routine will return 2 even if the two expressions
 ** really are equivalent.  If we cannot prove that the expressions are
 ** identical, we return 2 just to be safe.  So if this routine
@@ -79025,7 +79269,7 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
 ** just might result in some slightly slower code.  But returning
 ** an incorrect 0 or 1 could lead to a malfunction.
 */
-SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB){
+SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){
   if( pA==0||pB==0 ){
     return pB==pA ? 0 : 2;
   }
@@ -79035,19 +79279,22 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB){
     return 2;
   }
   if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
-  if( pA->op!=pB->op ){
-    if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB)<2 ){
+  if( pA->op!=pB->op && (pA->op!=TK_REGISTER || pA->op2!=pB->op) ){
+    if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB, iTab)<2 ){
       return 1;
     }
-    if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft)<2 ){
+    if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft, iTab)<2 ){
       return 1;
     }
     return 2;
   }
-  if( sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 2;
-  if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2;
-  if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2;
-  if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2;
+  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( pA->iColumn!=pB->iColumn ) return 2;
+  if( pA->iTable!=pB->iTable 
+   && pA->op!=TK_REGISTER
+   && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
   if( ExprHasProperty(pA, EP_IntValue) ){
     if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){
       return 2;
@@ -79065,6 +79312,9 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB){
 ** Compare two ExprList objects.  Return 0 if they are identical and 
 ** non-zero if they differ in any way.
 **
+** If any subelement of pB has Expr.iTable==(-1) then it is allowed
+** to compare equal to an equivalent element in pA with Expr.iTable==iTab.
+**
 ** This routine might return non-zero for equivalent ExprLists.  The
 ** only consequence will be disabled optimizations.  But this routine
 ** must never return 0 if the two ExprList objects are different, or
@@ -79073,7 +79323,7 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB){
 ** Two NULL pointers are considered to be the same.  But a NULL pointer
 ** always differs from a non-NULL pointer.
 */
-SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){
+SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){
   int i;
   if( pA==0 && pB==0 ) return 0;
   if( pA==0 || pB==0 ) return 1;
@@ -79082,7 +79332,46 @@ SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){
     Expr *pExprA = pA->a[i].pExpr;
     Expr *pExprB = pB->a[i].pExpr;
     if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1;
-    if( sqlite3ExprCompare(pExprA, pExprB) ) return 1;
+    if( sqlite3ExprCompare(pExprA, pExprB, iTab) ) return 1;
+  }
+  return 0;
+}
+
+/*
+** Return true if we can prove the pE2 will always be true if pE1 is
+** true.  Return false if we cannot complete the proof or if pE2 might
+** be false.  Examples:
+**
+**     pE1: x==5       pE2: x==5             Result: true
+**     pE1: x>0        pE2: x==5             Result: false
+**     pE1: x=21       pE2: x=21 OR y=43     Result: true
+**     pE1: x!=123     pE2: x IS NOT NULL    Result: true
+**     pE1: x!=?1      pE2: x IS NOT NULL    Result: true
+**     pE1: x IS NULL  pE2: x IS NOT NULL    Result: false
+**     pE1: x IS ?2    pE2: x IS NOT NULL    Reuslt: false
+**
+** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has
+** Expr.iTable<0 then assume a table number given by iTab.
+**
+** When in doubt, return false.  Returning true might give a performance
+** improvement.  Returning false might cause a performance reduction, but
+** it will always give the correct answer and is hence always safe.
+*/
+SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Expr *pE1, Expr *pE2, int iTab){
+  if( sqlite3ExprCompare(pE1, pE2, iTab)==0 ){
+    return 1;
+  }
+  if( pE2->op==TK_OR
+   && (sqlite3ExprImpliesExpr(pE1, pE2->pLeft, iTab)
+             || sqlite3ExprImpliesExpr(pE1, pE2->pRight, iTab) )
+  ){
+    return 1;
+  }
+  if( pE2->op==TK_NOTNULL
+   && sqlite3ExprCompare(pE1->pLeft, pE2->pLeft, iTab)==0
+   && (pE1->op!=TK_ISNULL && pE1->op!=TK_IS)
+  ){
+    return 1;
   }
   return 0;
 }
@@ -79267,7 +79556,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
         */
         struct AggInfo_func *pItem = pAggInfo->aFunc;
         for(i=0; i<pAggInfo->nFunc; i++, pItem++){
-          if( sqlite3ExprCompare(pItem->pExpr, pExpr)==0 ){
+          if( sqlite3ExprCompare(pItem->pExpr, pExpr, -1)==0 ){
             break;
           }
         }
@@ -80269,7 +80558,7 @@ exit_begin_add_column:
 ** The sqlite_stat2 table is not created or used unless the SQLite version
 ** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled
 ** with SQLITE_ENABLE_STAT2.  The sqlite_stat2 table is deprecated.
-** The sqlite_stat2 table is superceded by sqlite_stat3, which is only
+** The sqlite_stat2 table is superseded by sqlite_stat3, which is only
 ** created and used by SQLite versions 3.7.9 and later and with
 ** SQLITE_ENABLE_STAT3 defined.  The fucntionality of sqlite_stat3
 ** is a superset of sqlite_stat2.  
@@ -80684,6 +80973,7 @@ static void analyzeOneTable(
   int endOfLoop;               /* The end of the loop */
   int jZeroRows = -1;          /* Jump from here if number of rows is zero */
   int iDb;                     /* Index of database containing pTab */
+  u8 needTableCnt = 1;         /* True to count the table */
   int regTabname = iMem++;     /* Register containing table name */
   int regIdxname = iMem++;     /* Register containing index name */
   int regStat1 = iMem++;       /* The stat column of sqlite_stat1 */
@@ -80743,6 +81033,7 @@ static void analyzeOneTable(
     int *aChngAddr;              /* Array of jump instruction addresses */
 
     if( pOnlyIdx && pOnlyIdx!=pIdx ) continue;
+    if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0;
     VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName));
     nCol = pIdx->nColumn;
     aChngAddr = sqlite3DbMallocRaw(db, sizeof(int)*nCol);
@@ -80902,9 +81193,7 @@ static void analyzeOneTable(
     ** is never possible.
     */
     sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regStat1);
-    if( jZeroRows<0 ){
-      jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, iMem);
-    }
+    jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, iMem);
     for(i=0; i<nCol; i++){
       sqlite3VdbeAddOp4(v, OP_String8, 0, regTemp, 0, " ", 0);
       sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1);
@@ -80914,32 +81203,31 @@ static void analyzeOneTable(
       sqlite3VdbeAddOp1(v, OP_ToInt, regTemp);
       sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1);
     }
+    if( pIdx->pPartIdxWhere!=0 ) sqlite3VdbeJumpHere(v, jZeroRows);
     sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
     sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
     sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
     sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
+    if( pIdx->pPartIdxWhere==0 ) sqlite3VdbeJumpHere(v, jZeroRows);
   }
 
-  /* If the table has no indices, create a single sqlite_stat1 entry
-  ** containing NULL as the index name and the row count as the content.
+  /* Create a single sqlite_stat1 entry containing NULL as the index
+  ** name and the row count as the content.
   */
-  if( pTab->pIndex==0 ){
+  if( pOnlyIdx==0 && needTableCnt ){
     sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pTab->tnum, iDb);
     VdbeComment((v, "%s", pTab->zName));
     sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat1);
     sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);
     jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1);
-  }else{
+    sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
+    sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
+    sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
+    sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
+    sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
     sqlite3VdbeJumpHere(v, jZeroRows);
-    jZeroRows = sqlite3VdbeAddOp0(v, OP_Goto);
   }
-  sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
-  sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
-  sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
-  sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
-  sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
   if( pParse->nMem<regRec ) pParse->nMem = regRec;
-  sqlite3VdbeJumpHere(v, jZeroRows);
 }
 
 
@@ -81122,8 +81410,10 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
       v = v*10 + c - '0';
       z++;
     }
-    if( i==0 ) pTable->nRowEst = v;
-    if( pIndex==0 ) break;
+    if( i==0 && (pIndex==0 || pIndex->pPartIdxWhere==0) ){
+      if( v>0 ) pTable->nRowEst = v;
+      if( pIndex==0 ) break;
+    }
     pIndex->aiRowEst[i] = v;
     if( *z==' ' ) z++;
     if( strcmp(z, "unordered")==0 ){
@@ -81527,6 +81817,9 @@ static void attachFunc(
     sqlite3PagerLockingMode(pPager, db->dfltLockMode);
     sqlite3BtreeSecureDelete(aNew->pBt,
                              sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) );
+#ifndef SQLITE_OMIT_PAGER_PRAGMAS
+    sqlite3BtreeSetPagerFlags(aNew->pBt, 3 | (db->flags & PAGER_FLAGS_MASK));
+#endif
   }
   aNew->safety_level = 3;
   aNew->zName = sqlite3DbStrDup(db, zName);
@@ -82563,6 +82856,7 @@ static void freeIndex(sqlite3 *db, Index *p){
 #ifndef SQLITE_OMIT_ANALYZE
   sqlite3DeleteIndexSamples(db, p);
 #endif
+  sqlite3ExprDelete(db, p->pPartIdxWhere);
   sqlite3DbFree(db, p->zColAff);
   sqlite3DbFree(db, p);
 }
@@ -83406,7 +83700,8 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey(
 #endif
   }else{
     Index *p;
-    p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0);
+    p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0,
+                           0, sortOrder, 0);
     if( p ){
       p->autoIndex = 2;
     }
@@ -83457,6 +83752,7 @@ SQLITE_PRIVATE void sqlite3AddCollateType(Parse *pParse, Token *pToken){
 
   if( sqlite3LocateCollSeq(pParse, zColl) ){
     Index *pIdx;
+    sqlite3DbFree(db, p->aCol[i].zColl);
     p->aCol[i].zColl = zColl;
   
     /* If the column is declared as "<name> PRIMARY KEY COLLATE <type>",
@@ -83700,26 +83996,7 @@ SQLITE_PRIVATE void sqlite3EndTable(
   /* Resolve names in all CHECK constraint expressions.
   */
   if( p->pCheck ){
-    SrcList sSrc;                   /* Fake SrcList for pParse->pNewTable */
-    NameContext sNC;                /* Name context for pParse->pNewTable */
-    ExprList *pList;                /* List of all CHECK constraints */
-    int i;                          /* Loop counter */
-
-    memset(&sNC, 0, sizeof(sNC));
-    memset(&sSrc, 0, sizeof(sSrc));
-    sSrc.nSrc = 1;
-    sSrc.a[0].zName = p->zName;
-    sSrc.a[0].pTab = p;
-    sSrc.a[0].iCursor = -1;
-    sNC.pParse = pParse;
-    sNC.pSrcList = &sSrc;
-    sNC.ncFlags = NC_IsCheck;
-    pList = p->pCheck;
-    for(i=0; i<pList->nExpr; i++){
-      if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){
-        return;
-      }
-    }
+    sqlite3ResolveSelfReference(pParse, p, NC_IsCheck, 0, p->pCheck);
   }
 #endif /* !defined(SQLITE_OMIT_CHECK) */
 
@@ -84571,6 +84848,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
   int addr1;                     /* Address of top of loop */
   int addr2;                     /* Address to jump to for next iteration */
   int tnum;                      /* Root page of index */
+  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 */
@@ -84610,8 +84888,9 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
   addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
   regRecord = sqlite3GetTempReg(pParse);
 
-  sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
+  sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1, &iPartIdxLabel);
   sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
+  sqlite3VdbeResolveLabel(v, iPartIdxLabel);
   sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
   sqlite3VdbeJumpHere(v, addr1);
   addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0);
@@ -84662,7 +84941,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
   ExprList *pList,   /* A list of columns to be indexed */
   int onError,       /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
   Token *pStart,     /* The CREATE token that begins this statement */
-  Token *pEnd,       /* The ")" that closes the CREATE INDEX statement */
+  Expr *pPIWhere,    /* WHERE clause for partial indices */
   int sortOrder,     /* Sort order of primary key when pList==NULL */
   int ifNotExist     /* Omit error if index already exists */
 ){
@@ -84684,7 +84963,6 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
   int nExtra = 0;
   char *zExtra;
 
-  assert( pStart==0 || pEnd!=0 ); /* pEnd must be non-NULL if pStart is */
   assert( pParse->nErr==0 );      /* Never called with prior errors */
   if( db->mallocFailed || IN_DECLARE_VTAB ){
     goto exit_create_index;
@@ -84730,7 +85008,12 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
     pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]);
     assert( db->mallocFailed==0 || pTab==0 );
     if( pTab==0 ) goto exit_create_index;
-    assert( db->aDb[iDb].pSchema==pTab->pSchema );
+    if( iDb==1 && db->aDb[iDb].pSchema!=pTab->pSchema ){
+      sqlite3ErrorMsg(pParse, 
+           "cannot create a TEMP index on non-TEMP table \"%s\"",
+           pTab->zName);
+      goto exit_create_index;
+    }
   }else{
     assert( pName==0 );
     assert( pStart==0 );
@@ -84876,8 +85159,14 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
   pIndex->pTable = pTab;
   pIndex->nColumn = pList->nExpr;
   pIndex->onError = (u8)onError;
+  pIndex->uniqNotNull = onError==OE_Abort;
   pIndex->autoIndex = (u8)(pName==0);
   pIndex->pSchema = db->aDb[iDb].pSchema;
+  if( pPIWhere ){
+    sqlite3ResolveSelfReference(pParse, pTab, NC_PartIdx, pPIWhere, 0);
+    pIndex->pPartIdxWhere = pPIWhere;
+    pPIWhere = 0;
+  }
   assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
 
   /* Check to see if we should honor DESC requests on index columns
@@ -84934,6 +85223,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
     pIndex->azColl[i] = zColl;
     requestedSortOrder = pListItem->sortOrder & sortOrderMask;
     pIndex->aSortOrder[i] = (u8)requestedSortOrder;
+    if( pTab->aCol[j].notNull==0 ) pIndex->uniqNotNull = 0;
   }
   sqlite3DefaultRowEst(pIndex);
 
@@ -85032,7 +85322,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
   ** has just been created, it contains no data and the index initialization
   ** step can be skipped.
   */
-  else{ /* if( db->init.busy==0 ) */
+  else if( pParse->nErr==0 ){
     Vdbe *v;
     char *zStmt;
     int iMem = ++pParse->nMem;
@@ -85050,12 +85340,11 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
     ** the zStmt variable
     */
     if( pStart ){
-      assert( pEnd!=0 );
+      int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n;
+      if( pName->z[n-1]==';' ) n--;
       /* A named index with an explicit CREATE INDEX statement */
       zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s",
-        onError==OE_None ? "" : " UNIQUE",
-        (int)(pEnd->z - pName->z) + 1,
-        pName->z);
+        onError==OE_None ? "" : " UNIQUE", n, pName->z);
     }else{
       /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */
       /* zStmt = sqlite3MPrintf(""); */
@@ -85111,10 +85400,8 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
 
   /* Clean up before exiting */
 exit_create_index:
-  if( pIndex ){
-    sqlite3DbFree(db, pIndex->zColAff);
-    sqlite3DbFree(db, pIndex);
-  }
+  if( pIndex ) freeIndex(db, pIndex);
+  sqlite3ExprDelete(db, pPIWhere);
   sqlite3ExprListDelete(db, pList);
   sqlite3SrcListDelete(db, pTblName);
   sqlite3DbFree(db, zName);
@@ -85365,7 +85652,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
     }
     pSrc = pNew;
     nGot = (sqlite3DbMallocSize(db, pNew) - sizeof(*pSrc))/sizeof(pSrc->a[0])+1;
-    pSrc->nAlloc = (u16)nGot;
+    pSrc->nAlloc = (u8)nGot;
   }
 
   /* Move existing slots that come after the newly inserted slots
@@ -85373,7 +85660,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
   for(i=pSrc->nSrc-1; i>=iStart; i--){
     pSrc->a[i+nExtra] = pSrc->a[i];
   }
-  pSrc->nSrc += (i16)nExtra;
+  pSrc->nSrc += (i8)nExtra;
 
   /* Zero the newly allocated slots */
   memset(&pSrc->a[iStart], 0, sizeof(pSrc->a[0])*nExtra);
@@ -85992,25 +86279,20 @@ SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){
 SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
   int i;
   int nCol = pIdx->nColumn;
-  int nBytes = sizeof(KeyInfo) + (nCol-1)*sizeof(CollSeq*) + nCol;
-  sqlite3 *db = pParse->db;
-  KeyInfo *pKey = (KeyInfo *)sqlite3DbMallocZero(db, nBytes);
+  KeyInfo *pKey;
 
+  pKey = sqlite3KeyInfoAlloc(pParse->db, nCol);
   if( pKey ){
-    pKey->db = pParse->db;
-    pKey->aSortOrder = (u8 *)&(pKey->aColl[nCol]);
-    assert( &pKey->aSortOrder[nCol]==&(((u8 *)pKey)[nBytes]) );
     for(i=0; i<nCol; i++){
       char *zColl = pIdx->azColl[i];
       assert( zColl );
       pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl);
       pKey->aSortOrder[i] = pIdx->aSortOrder[i];
     }
-    pKey->nField = (u16)nCol;
   }
 
   if( pParse->nErr ){
-    sqlite3DbFree(db, pKey);
+    sqlite3DbFree(pParse->db, pKey);
     pKey = 0;
   }
   return pKey;
@@ -87090,11 +87372,14 @@ SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(
   int i;
   Index *pIdx;
   int r1;
+  int iPartIdxLabel;
+  Vdbe *v = pParse->pVdbe;
 
   for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
     if( aRegIdx!=0 && aRegIdx[i-1]==0 ) continue;
-    r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 0);
-    sqlite3VdbeAddOp3(pParse->pVdbe, OP_IdxDelete, iCur+i, r1,pIdx->nColumn+1);
+    r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 0, &iPartIdxLabel);
+    sqlite3VdbeAddOp3(v, OP_IdxDelete, iCur+i, r1, pIdx->nColumn+1);
+    sqlite3VdbeResolveLabel(v, iPartIdxLabel);
   }
 }
 
@@ -87108,13 +87393,21 @@ SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(
 ** registers that holds the elements of the index key.  The
 ** block of registers has already been deallocated by the time
 ** this routine returns.
+**
+** If *piPartIdxLabel is not NULL, fill it in with a label and jump
+** to that label if pIdx is a partial index that should be skipped.
+** A partial index should be skipped if its WHERE clause evaluates
+** to false or null.  If pIdx is not a partial index, *piPartIdxLabel
+** will be set to zero which is an empty label that is ignored by
+** sqlite3VdbeResolveLabel().
 */
 SQLITE_PRIVATE int sqlite3GenerateIndexKey(
-  Parse *pParse,     /* Parsing context */
-  Index *pIdx,       /* The index for which to generate a key */
-  int iCur,          /* Cursor number for the pIdx->pTable table */
-  int regOut,        /* Write the new index key to this register */
-  int doMakeRec      /* Run the OP_MakeRecord instruction if true */
+  Parse *pParse,       /* Parsing context */
+  Index *pIdx,         /* The index for which to generate a key */
+  int iCur,            /* Cursor number for the pIdx->pTable table */
+  int regOut,          /* Write the new index key to this register */
+  int doMakeRec,       /* Run the OP_MakeRecord instruction if true */
+  int *piPartIdxLabel  /* OUT: Jump to this label to skip partial index */
 ){
   Vdbe *v = pParse->pVdbe;
   int j;
@@ -87122,6 +87415,16 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey(
   int regBase;
   int nCol;
 
+  if( piPartIdxLabel ){
+    if( pIdx->pPartIdxWhere ){
+      *piPartIdxLabel = sqlite3VdbeMakeLabel(v);
+      pParse->iPartIdxTab = iCur;
+      sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, 
+                         SQLITE_JUMPIFNULL);
+    }else{
+      *piPartIdxLabel = 0;
+    }
+  }
   nCol = pIdx->nColumn;
   regBase = sqlite3GetTempRange(pParse, nCol+1);
   sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol);
@@ -87380,7 +87683,7 @@ static void instrFunc(
 **
 ** If p1 is negative, then we begin abs(p1) from the end of x[].
 **
-** If p2 is negative, return the p2 characters preceeding p1.
+** If p2 is negative, return the p2 characters preceding p1.
 */
 static void substrFunc(
   sqlite3_context *context,
@@ -88039,10 +88342,6 @@ static const char hexdigits[] = {
 };
 
 /*
-** EXPERIMENTAL - This is not an official function.  The interface may
-** change.  This function may disappear.  Do not write code that depends
-** on this function.
-**
 ** Implementation of the QUOTE() function.  This function takes a single
 ** argument.  If the argument is numeric, the return value is the same as
 ** the argument.  If the argument is NULL, the return value is the string
@@ -88231,7 +88530,7 @@ static void zeroblobFunc(
 /*
 ** The replace() function.  Three arguments are all strings: call
 ** them A, B, and C. The result is also a string which is derived
-** from A by replacing every occurance of B with C.  The match
+** from A by replacing every occurrence of B with C.  The match
 ** must be exact.  Collating sequences are not used.
 */
 static void replaceFunc(
@@ -88678,9 +88977,9 @@ static void groupConcatFinalize(sqlite3_context *context){
   StrAccum *pAccum;
   pAccum = sqlite3_aggregate_context(context, 0);
   if( pAccum ){
-    if( pAccum->tooBig ){
+    if( pAccum->accError==STRACCUM_TOOBIG ){
       sqlite3_result_error_toobig(context);
-    }else if( pAccum->mallocFailed ){
+    }else if( pAccum->accError==STRACCUM_NOMEM ){
       sqlite3_result_error_nomem(context);
     }else{    
       sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1, 
@@ -89298,7 +89597,10 @@ static void fkLookupParent(
     }
   }
 
-  if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){
+  if( !pFKey->isDeferred && !(pParse->db->flags & SQLITE_DeferFKs)
+   && !pParse->pToplevel 
+   && !pParse->isMultiWrite 
+  ){
     /* Special case: If this is an INSERT statement that will insert exactly
     ** one row into the table, raise a constraint immediately instead of
     ** incrementing a counter. This is necessary as the VM code is being
@@ -89689,7 +89991,9 @@ SQLITE_PRIVATE void sqlite3FkCheck(
     SrcList *pSrc;
     int *aiCol = 0;
 
-    if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){
+    if( !pFKey->isDeferred && !(db->flags & SQLITE_DeferFKs) 
+     && !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.  */
@@ -91484,9 +91788,19 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
   for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
     int regIdx;
     int regR;
+    int addrSkipRow = 0;
 
     if( aRegIdx[iCur]==0 ) continue;  /* Skip unused indices */
 
+    if( pIdx->pPartIdxWhere ){
+      sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[iCur]);
+      addrSkipRow = sqlite3VdbeMakeLabel(v);
+      pParse->ckBase = regData;
+      sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, addrSkipRow,
+                         SQLITE_JUMPIFNULL);
+      pParse->ckBase = 0;
+    }
+
     /* Create a key for accessing the index entry */
     regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);
     for(i=0; i<pIdx->nColumn; i++){
@@ -91506,6 +91820,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
     onError = pIdx->onError;
     if( onError==OE_None ){ 
       sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
+      sqlite3VdbeResolveLabel(v, addrSkipRow);
       continue;  /* pIdx is not a UNIQUE index */
     }
     if( overrideError!=OE_Default ){
@@ -91575,6 +91890,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
       }
     }
     sqlite3VdbeJumpHere(v, j3);
+    sqlite3VdbeResolveLabel(v, addrSkipRow);
     sqlite3ReleaseTempReg(pParse, regR);
   }
   
@@ -91604,7 +91920,6 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
 ){
   int i;
   Vdbe *v;
-  int nIdx;
   Index *pIdx;
   u8 pik_flags;
   int regData;
@@ -91613,9 +91928,11 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
   v = sqlite3GetVdbe(pParse);
   assert( v!=0 );
   assert( pTab->pSelect==0 );  /* This table is not a VIEW */
-  for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
-  for(i=nIdx-1; i>=0; i--){
+  for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
     if( aRegIdx[i]==0 ) continue;
+    if( pIdx->pPartIdxWhere ){
+      sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
+    }
     sqlite3VdbeAddOp2(v, OP_IdxInsert, baseCur+i+1, aRegIdx[i]);
     if( useSeekResult ){
       sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
@@ -91717,6 +92034,7 @@ static int xferCompatibleCollation(const char *z1, const char *z2){
 **    *   The same DESC and ASC markings occurs on all columns
 **    *   The same onError processing (OE_Abort, OE_Ignore, etc)
 **    *   The same collating sequence on each column
+**    *   The index has the exact same WHERE clause
 */
 static int xferCompatibleIndex(Index *pDest, Index *pSrc){
   int i;
@@ -91739,6 +92057,9 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){
       return 0;   /* Different collating sequences */
     }
   }
+  if( sqlite3ExprCompare(pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1) ){
+    return 0;     /* Different WHERE clauses */
+  }
 
   /* If no test above fails then the indices must be compatible */
   return 1;
@@ -91894,7 +92215,7 @@ static int xferOptimization(
     }
   }
 #ifndef SQLITE_OMIT_CHECK
-  if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck, pDest->pCheck) ){
+  if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){
     return 0;   /* Tables have different CHECK constraints.  Ticket #2252 */
   }
 #endif
@@ -92651,11 +92972,14 @@ struct sqlite3_api_routines {
   ** extension */
 # define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api=0;
 # define SQLITE_EXTENSION_INIT2(v)  sqlite3_api=v;
+# define SQLITE_EXTENSION_INIT3     \
+    extern const sqlite3_api_routines *sqlite3_api;
 #else
   /* This case when the file is being statically linked into the 
   ** application */
 # define SQLITE_EXTENSION_INIT1     /*no-op*/
 # define SQLITE_EXTENSION_INIT2(v)  (void)v; /* unused parameter */
+# define SQLITE_EXTENSION_INIT3     /*no-op*/
 #endif
 
 #endif /* _SQLITE3EXT_H_ */
@@ -93313,6 +93637,35 @@ SQLITE_API int sqlite3_auto_extension(void (*xInit)(void)){
 }
 
 /*
+** Cancel a prior call to sqlite3_auto_extension.  Remove xInit from the
+** set of routines that is invoked for each new database connection, if it
+** is currently on the list.  If xInit is not on the list, then this
+** routine is a no-op.
+**
+** 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)){
+#if SQLITE_THREADSAFE
+  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
+#endif
+  int i;
+  int n = 0;
+  wsdAutoextInit;
+  sqlite3_mutex_enter(mutex);
+  for(i=wsdAutoext.nExt-1; i>=0; i--){
+    if( wsdAutoext.aExt[i]==xInit ){
+      wsdAutoext.nExt--;
+      wsdAutoext.aExt[i] = wsdAutoext.aExt[wsdAutoext.nExt];
+      n++;
+      break;
+    }
+  }
+  sqlite3_mutex_leave(mutex);
+  return n;
+}
+
+/*
 ** Reset the automatic extension loading mechanism.
 */
 SQLITE_API void sqlite3_reset_auto_extension(void){
@@ -93533,6 +93886,36 @@ static void returnSingleInt(Parse *pParse, const char *zLabel, i64 value){
   sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1);
 }
 
+
+/*
+** Set the safety_level and pager flags for pager iDb.  Or if iDb<0
+** set these values for all pagers.
+*/
+#ifndef SQLITE_OMIT_PAGER_PRAGMAS
+static void setAllPagerFlags(sqlite3 *db){
+  if( db->autoCommit ){
+    Db *pDb = db->aDb;
+    int n = db->nDb;
+    assert( SQLITE_FullFSync==PAGER_FULLFSYNC );
+    assert( SQLITE_CkptFullFSync==PAGER_CKPT_FULLFSYNC );
+    assert( SQLITE_CacheSpill==PAGER_CACHESPILL );
+    assert( (PAGER_FULLFSYNC | PAGER_CKPT_FULLFSYNC | PAGER_CACHESPILL)
+             ==  PAGER_FLAGS_MASK );
+    assert( (pDb->safety_level & PAGER_SYNCHRONOUS_MASK)==pDb->safety_level );
+    while( (n--) > 0 ){
+      if( pDb->pBt ){
+        sqlite3BtreeSetPagerFlags(pDb->pBt,
+                 pDb->safety_level | (db->flags & PAGER_FLAGS_MASK) );
+      }
+      pDb++;
+    }
+  }
+}
+#else
+# define setAllPagerFlags(X)  /* no-op */
+#endif
+
+
 #ifndef SQLITE_OMIT_FLAG_PRAGMAS
 /*
 ** Check to see if zRight and zLeft refer to a pragma that queries
@@ -93551,7 +93934,9 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
     { "legacy_file_format",       SQLITE_LegacyFileFmt },
     { "fullfsync",                SQLITE_FullFSync     },
     { "checkpoint_fullfsync",     SQLITE_CkptFullFSync },
+    { "cache_spill",              SQLITE_CacheSpill    },
     { "reverse_unordered_selects", SQLITE_ReverseOrder  },
+    { "query_only",               SQLITE_QueryOnly     },
 #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
     { "automatic_index",          SQLITE_AutoIndex     },
 #endif
@@ -93572,12 +93957,13 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
     /* TODO: Maybe it shouldn't be possible to change the ReadUncommitted
     ** flag if there are any active statements. */
     { "read_uncommitted",         SQLITE_ReadUncommitted },
-    { "recursive_triggers",       SQLITE_RecTriggers },
+    { "recursive_triggers",       SQLITE_RecTriggers   },
 
     /* This flag may only be set if both foreign-key and trigger support
     ** are present in the build.  */
 #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
-    { "foreign_keys",             SQLITE_ForeignKeys },
+    { "foreign_keys",             SQLITE_ForeignKeys   },
+    { "defer_foreign_keys",       SQLITE_DeferFKs      },
 #endif
   };
   int i;
@@ -93603,6 +93989,7 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
             db->flags |= mask;
           }else{
             db->flags &= ~mask;
+            if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0;
           }
 
           /* Many of the flag-pragmas modify the code generated by the SQL 
@@ -94149,11 +94536,15 @@ SQLITE_PRIVATE void sqlite3Pragma(
       }
     }
     sz = -1;
-    if( sqlite3_file_control(db,zDb,SQLITE_FCNTL_MMAP_SIZE,&sz)==SQLITE_OK ){
+    rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_MMAP_SIZE, &sz);
 #if SQLITE_MAX_MMAP_SIZE==0
-      sz = 0;
+    sz = 0;
 #endif
+    if( rc==SQLITE_OK ){
       returnSingleInt(pParse, "mmap_size", sz);
+    }else if( rc!=SQLITE_NOTFOUND ){
+      pParse->nErr++;
+      pParse->rc = rc;
     }
   }else
 
@@ -94334,6 +94725,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
             "Safety level may not be changed inside a transaction");
       }else{
         pDb->safety_level = getSafetyLevel(zRight,0,1)+1;
+        setAllPagerFlags(db);
       }
     }
   }else
@@ -94341,8 +94733,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
 
 #ifndef SQLITE_OMIT_FLAG_PRAGMAS
   if( flagPragma(pParse, zLeft, zRight) ){
-    /* The flagPragma() subroutine also generates any necessary code
-    ** there is nothing more to do here */
+    setAllPagerFlags(db);
   }else
 #endif /* SQLITE_OMIT_FLAG_PRAGMAS */
 
@@ -94738,7 +95129,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
 #endif
 
 #ifndef SQLITE_OMIT_INTEGRITY_CHECK
-  /* Pragma "quick_check" is an experimental reduced version of 
+  /* Pragma "quick_check" is reduced version of 
   ** integrity_check designed to detect most database corruption
   ** without most of the overhead of a full integrity-check.
   */
@@ -94822,9 +95213,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
       }
 
       /* Make sure sufficient number of registers have been allocated */
-      if( pParse->nMem < cnt+4 ){
-        pParse->nMem = cnt+4;
-      }
+      pParse->nMem = MAX( pParse->nMem, cnt+7 );
 
       /* Do the b-tree integrity checks */
       sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1);
@@ -94849,12 +95238,15 @@ SQLITE_PRIVATE void sqlite3Pragma(
         addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1);  /* Stop if out of errors */
         sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
         sqlite3VdbeJumpHere(v, addr);
+        sqlite3ExprCacheClear(pParse);
         sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
-        sqlite3VdbeAddOp2(v, OP_Integer, 0, 2);  /* reg(2) will count entries */
-        loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0);
-        sqlite3VdbeAddOp2(v, OP_AddImm, 2, 1);   /* increment entry count */
         for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
-          int jmp2;
+          sqlite3VdbeAddOp2(v, OP_Integer, 0, 7+j); /* index entries counter */
+        }
+        pParse->nMem = MAX(pParse->nMem, 7+j);
+        loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0) + 1;
+        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+          int jmp2, jmp3;
           int r1;
           static const VdbeOpList idxErr[] = {
             { OP_AddImm,      1, -1,  0},
@@ -94869,7 +95261,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
             { OP_IfPos,       1,  0,  0},    /* 9 */
             { OP_Halt,        0,  0,  0},
           };
-          r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 0);
+          r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 0, &jmp3);
+          sqlite3VdbeAddOp2(v, OP_AddImm, 7+j, 1);  /* increment entry count */
           jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, j+2, 0, r1, pIdx->nColumn+1);
           addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
           sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC);
@@ -94877,35 +95270,25 @@ SQLITE_PRIVATE void sqlite3Pragma(
           sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_TRANSIENT);
           sqlite3VdbeJumpHere(v, addr+9);
           sqlite3VdbeJumpHere(v, jmp2);
+          sqlite3VdbeResolveLabel(v, jmp3);
         }
-        sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop+1);
-        sqlite3VdbeJumpHere(v, loopTop);
+        sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop);
+        sqlite3VdbeJumpHere(v, loopTop-1);
+#ifndef SQLITE_OMIT_BTREECOUNT
+        sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, 
+                     "wrong # of entries in index ", P4_STATIC);
         for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
-          static const VdbeOpList cntIdx[] = {
-             { OP_Integer,      0,  3,  0},
-             { OP_Rewind,       0,  0,  0},  /* 1 */
-             { OP_AddImm,       3,  1,  0},
-             { OP_Next,         0,  0,  0},  /* 3 */
-             { OP_Eq,           2,  0,  3},  /* 4 */
-             { OP_AddImm,       1, -1,  0},
-             { OP_String8,      0,  2,  0},  /* 6 */
-             { OP_String8,      0,  3,  0},  /* 7 */
-             { OP_Concat,       3,  2,  2},
-             { OP_ResultRow,    2,  1,  0},
-          };
-          addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1);
+          addr = sqlite3VdbeCurrentAddr(v);
+          sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2);
           sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
-          sqlite3VdbeJumpHere(v, addr);
-          addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
-          sqlite3VdbeChangeP1(v, addr+1, j+2);
-          sqlite3VdbeChangeP2(v, addr+1, addr+4);
-          sqlite3VdbeChangeP1(v, addr+3, j+2);
-          sqlite3VdbeChangeP2(v, addr+3, addr+2);
-          sqlite3VdbeJumpHere(v, addr+4);
-          sqlite3VdbeChangeP4(v, addr+6, 
-                     "wrong # of entries in index ", P4_STATIC);
-          sqlite3VdbeChangeP4(v, addr+7, pIdx->zName, P4_TRANSIENT);
+          sqlite3VdbeAddOp2(v, OP_Count, j+2, 3);
+          sqlite3VdbeAddOp3(v, OP_Eq, 7+j, addr+8, 3);
+          sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
+          sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pIdx->zName, P4_TRANSIENT);
+          sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
+          sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1);
         }
+#endif /* SQLITE_OMIT_BTREECOUNT */
       } 
     }
     addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);
@@ -95196,10 +95579,10 @@ SQLITE_PRIVATE void sqlite3Pragma(
 
 #ifdef SQLITE_HAS_CODEC
   if( sqlite3StrICmp(zLeft, "key")==0 && zRight ){
-    sqlite3_key(db, zRight, sqlite3Strlen30(zRight));
+    sqlite3_key_v2(db, zDb, zRight, sqlite3Strlen30(zRight));
   }else
   if( sqlite3StrICmp(zLeft, "rekey")==0 && zRight ){
-    sqlite3_rekey(db, zRight, sqlite3Strlen30(zRight));
+    sqlite3_rekey_v2(db, zDb, zRight, sqlite3Strlen30(zRight));
   }else
   if( zRight && (sqlite3StrICmp(zLeft, "hexkey")==0 ||
                  sqlite3StrICmp(zLeft, "hexrekey")==0) ){
@@ -95211,9 +95594,9 @@ SQLITE_PRIVATE void sqlite3Pragma(
       zKey[i/2] = (h2 & 0x0f) | ((h1 & 0xf)<<4);
     }
     if( (zLeft[3] & 0xf)==0xb ){
-      sqlite3_key(db, zKey, i/2);
+      sqlite3_key_v2(db, zDb, zKey, i/2);
     }else{
-      sqlite3_rekey(db, zKey, i/2);
+      sqlite3_rekey_v2(db, zDb, zKey, i/2);
     }
   }else
 #endif
@@ -95235,17 +95618,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
  
   {/* Empty ELSE clause */}
 
-  /*
-  ** Reset the safety level, in case the fullfsync flag or synchronous
-  ** setting changed.
-  */
-#ifndef SQLITE_OMIT_PAGER_PRAGMAS
-  if( db->autoCommit ){
-    sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level,
-               (db->flags&SQLITE_FullFSync)!=0,
-               (db->flags&SQLITE_CkptFullFSync)!=0);
-  }
-#endif
 pragma_out:
   sqlite3DbFree(db, zLeft);
   sqlite3DbFree(db, zRight);
@@ -95848,7 +96220,7 @@ static int sqlite3Prepare(
   sqlite3VtabUnlockList(db);
 
   pParse->db = db;
-  pParse->nQueryLoop = (double)1;
+  pParse->nQueryLoop = 0;  /* Logarithmic, so 0 really means 1 */
   if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
     char *zSqlCopy;
     int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
@@ -95870,7 +96242,7 @@ static int sqlite3Prepare(
   }else{
     sqlite3RunParser(pParse, zSql, &zErrMsg);
   }
-  assert( 1==(int)pParse->nQueryLoop );
+  assert( 0==pParse->nQueryLoop );
 
   if( db->mallocFailed ){
     pParse->rc = SQLITE_NOMEM;
@@ -96066,6 +96438,12 @@ static int sqlite3Prepare16(
   if( !sqlite3SafetyCheckOk(db) ){
     return SQLITE_MISUSE_BKPT;
   }
+  if( nBytes>=0 ){
+    int sz;
+    const char *z = (const char*)zSql;
+    for(sz=0; sz<nBytes && (z[sz]!=0 || z[sz+1]!=0); sz += 2){}
+    nBytes = sz;
+  }
   sqlite3_mutex_enter(db->mutex);
   zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE);
   if( zSql8 ){
@@ -96234,7 +96612,7 @@ SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){
 }
 
 /*
-** Given 1 to 3 identifiers preceeding the JOIN keyword, determine the
+** Given 1 to 3 identifiers preceding the JOIN keyword, determine the
 ** type of join.  Return an integer constant that expresses that type
 ** in terms of the following bit values:
 **
@@ -96928,6 +97306,25 @@ static void selectInnerLoop(
 }
 
 /*
+** Allocate a KeyInfo object sufficient for an index of N columns.
+**
+** Actually, always allocate one extra column for the rowid at the end
+** of the index.  So the KeyInfo returned will have space sufficient for
+** N+1 columns.
+*/
+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N){
+  KeyInfo *p = sqlite3DbMallocZero(db, 
+                   sizeof(KeyInfo) + (N+1)*(sizeof(CollSeq*)+1));
+  if( p ){
+    p->aSortOrder = (u8*)&p->aColl[N+1];
+    p->nField = (u16)N;
+    p->enc = ENC(db);
+    p->db = db;
+  }
+  return p;
+}
+
+/*
 ** Given an expression list, generate a KeyInfo structure that records
 ** the collating sequence for each expression in that expression list.
 **
@@ -96943,25 +97340,19 @@ static void selectInnerLoop(
 ** P4_KEYINFO_HANDOFF is the usual way of dealing with this.
 */
 static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){
-  sqlite3 *db = pParse->db;
   int nExpr;
   KeyInfo *pInfo;
   struct ExprList_item *pItem;
+  sqlite3 *db = pParse->db;
   int i;
 
   nExpr = pList->nExpr;
-  pInfo = sqlite3DbMallocZero(db, sizeof(*pInfo) + nExpr*(sizeof(CollSeq*)+1) );
+  pInfo = sqlite3KeyInfoAlloc(db, nExpr);
   if( pInfo ){
-    pInfo->aSortOrder = (u8*)&pInfo->aColl[nExpr];
-    pInfo->nField = (u16)nExpr;
-    pInfo->enc = ENC(db);
-    pInfo->db = db;
     for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){
       CollSeq *pColl;
       pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
-      if( !pColl ){
-        pColl = db->pDfltColl;
-      }
+      if( !pColl ) pColl = db->pDfltColl;
       pInfo->aColl[i] = pColl;
       pInfo->aSortOrder[i] = pItem->sortOrder;
     }
@@ -97648,7 +98039,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
 
   /* 
   ** "LIMIT -1" always shows all rows.  There is some
-  ** contraversy about what the correct behavior should be.
+  ** controversy about what the correct behavior should be.
   ** The current implementation interprets "LIMIT 0" to mean
   ** no rows.
   */
@@ -97663,8 +98054,8 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
       VdbeComment((v, "LIMIT counter"));
       if( n==0 ){
         sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak);
-      }else{
-        if( p->nSelectRow > (double)n ) p->nSelectRow = (double)n;
+      }else if( n>=0 && p->nSelectRow>(u64)n ){
+        p->nSelectRow = n;
       }
     }else{
       sqlite3ExprCode(pParse, p->pLimit, iLimit);
@@ -97858,9 +98249,9 @@ static int multiSelect(
       p->nSelectRow += pPrior->nSelectRow;
       if( pPrior->pLimit
        && sqlite3ExprIsInteger(pPrior->pLimit, &nLimit)
-       && p->nSelectRow > (double)nLimit 
+       && nLimit>0 && p->nSelectRow > (u64)nLimit 
       ){
-        p->nSelectRow = (double)nLimit;
+        p->nSelectRow = nLimit;
       }
       if( addr ){
         sqlite3VdbeJumpHere(v, addr);
@@ -98067,23 +98458,17 @@ static int multiSelect(
 
     assert( p->pRightmost==p );
     nCol = p->pEList->nExpr;
-    pKeyInfo = sqlite3DbMallocZero(db,
-                       sizeof(*pKeyInfo)+nCol*(sizeof(CollSeq*) + 1));
+    pKeyInfo = sqlite3KeyInfoAlloc(db, nCol);
     if( !pKeyInfo ){
       rc = SQLITE_NOMEM;
       goto multi_select_end;
     }
-
-    pKeyInfo->enc = ENC(db);
-    pKeyInfo->nField = (u16)nCol;
-
     for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
       *apColl = multiSelectCollSeq(pParse, p, i);
       if( 0==*apColl ){
         *apColl = db->pDfltColl;
       }
     }
-    pKeyInfo->aSortOrder = (u8*)apColl;
 
     for(pLoop=p; pLoop; pLoop=pLoop->pPrior){
       for(i=0; i<2; i++){
@@ -98452,12 +98837,8 @@ static int multiSelectOrderBy(
       assert( pItem->iOrderByCol>0  && pItem->iOrderByCol<=p->pEList->nExpr );
       aPermute[i] = pItem->iOrderByCol - 1;
     }
-    pKeyMerge =
-      sqlite3DbMallocRaw(db, sizeof(*pKeyMerge)+nOrderBy*(sizeof(CollSeq*)+1));
+    pKeyMerge = sqlite3KeyInfoAlloc(db, nOrderBy);
     if( pKeyMerge ){
-      pKeyMerge->aSortOrder = (u8*)&pKeyMerge->aColl[nOrderBy];
-      pKeyMerge->nField = (u16)nOrderBy;
-      pKeyMerge->enc = ENC(db);
       for(i=0; i<nOrderBy; i++){
         CollSeq *pColl;
         Expr *pTerm = pOrderBy->a[i].pExpr;
@@ -98494,12 +98875,8 @@ static int multiSelectOrderBy(
     regPrev = pParse->nMem+1;
     pParse->nMem += nExpr+1;
     sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev);
-    pKeyDup = sqlite3DbMallocZero(db,
-                  sizeof(*pKeyDup) + nExpr*(sizeof(CollSeq*)+1) );
+    pKeyDup = sqlite3KeyInfoAlloc(db, nExpr);
     if( pKeyDup ){
-      pKeyDup->aSortOrder = (u8*)&pKeyDup->aColl[nExpr];
-      pKeyDup->nField = (u16)nExpr;
-      pKeyDup->enc = ENC(db);
       for(i=0; i<nExpr; i++){
         pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
         pKeyDup->aSortOrder[i] = 0;
@@ -99765,10 +100142,12 @@ static int exprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
 static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
   Walker w;
   memset(&w, 0, sizeof(w));
-  w.xSelectCallback = convertCompoundSelectToSubquery;
   w.xExprCallback = exprWalkNoop;
   w.pParse = pParse;
-  sqlite3WalkSelect(&w, pSelect);
+  if( pParse->hasCompound ){
+    w.xSelectCallback = convertCompoundSelectToSubquery;
+    sqlite3WalkSelect(&w, pSelect);
+  }
   w.xSelectCallback = selectExpander;
   sqlite3WalkSelect(&w, pSelect);
 }
@@ -100009,11 +100388,10 @@ static void explainSimpleCount(
   Index *pIdx                     /* Index used to optimize scan, or NULL */
 ){
   if( pParse->explain==2 ){
-    char *zEqp = sqlite3MPrintf(pParse->db, "SCAN TABLE %s %s%s(~%d rows)",
+    char *zEqp = sqlite3MPrintf(pParse->db, "SCAN TABLE %s%s%s",
         pTab->zName, 
-        pIdx ? "USING COVERING INDEX " : "",
-        pIdx ? pIdx->zName : "",
-        pTab->nRowEst
+        pIdx ? " USING COVERING INDEX " : "",
+        pIdx ? pIdx->zName : ""
     );
     sqlite3VdbeAddOp4(
         pParse->pVdbe, OP_Explain, pParse->iSelectId, 0, 0, zEqp, P4_DYNAMIC
@@ -100171,7 +100549,7 @@ SQLITE_PRIVATE int sqlite3Select(
     }
 
     /* Increment Parse.nHeight by the height of the largest expression
-    ** tree refered to by this, the parent select. The child select
+    ** tree referred to by this, the parent select. The child select
     ** may contain expression trees of at most
     ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit
     ** more conservative than necessary, but much easier than enforcing
@@ -100303,7 +100681,7 @@ SQLITE_PRIVATE int sqlite3Select(
   ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER
   ** to disable this optimization for testing purposes.
   */
-  if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy)==0
+  if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy, -1)==0
          && OptimizationEnabled(db, SQLITE_GroupByOrder) ){
     pOrderBy = 0;
   }
@@ -100324,7 +100702,7 @@ SQLITE_PRIVATE int sqlite3Select(
   ** BY and DISTINCT, and an index or separate temp-table for the other.
   */
   if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct 
-   && sqlite3ExprListCompare(pOrderBy, p->pEList)==0
+   && sqlite3ExprListCompare(pOrderBy, p->pEList, -1)==0
   ){
     p->selFlags &= ~SF_Distinct;
     p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
@@ -100364,7 +100742,7 @@ SQLITE_PRIVATE int sqlite3Select(
   /* Set the limiter.
   */
   iEnd = sqlite3VdbeMakeLabel(v);
-  p->nSelectRow = (double)LARGEST_INT64;
+  p->nSelectRow = LARGEST_INT64;
   computeLimitRegisters(pParse, p, iEnd);
   if( p->iLimit==0 && addrSortIndex>=0 ){
     sqlite3VdbeGetOp(v, addrSortIndex)->opcode = OP_SorterOpen;
@@ -100387,14 +100765,19 @@ SQLITE_PRIVATE int sqlite3Select(
 
   if( !isAgg && pGroupBy==0 ){
     /* No aggregate functions and no GROUP BY clause */
-    ExprList *pDist = (sDistinct.isTnct ? p->pEList : 0);
+    u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0);
 
     /* Begin the database scan. */
-    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pOrderBy, pDist, 0,0);
+    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pOrderBy, p->pEList,
+                               wctrlFlags, 0);
     if( pWInfo==0 ) goto select_end;
-    if( pWInfo->nRowOut < p->nSelectRow ) p->nSelectRow = pWInfo->nRowOut;
-    if( pWInfo->eDistinct ) sDistinct.eTnctType = pWInfo->eDistinct;
-    if( pOrderBy && pWInfo->nOBSat==pOrderBy->nExpr ) pOrderBy = 0;
+    if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){
+      p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo);
+    }
+    if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){
+      sDistinct.eTnctType = sqlite3WhereIsDistinct(pWInfo);
+    }
+    if( pOrderBy && sqlite3WhereIsOrdered(pWInfo) ) pOrderBy = 0;
 
     /* If sorting index that was created by a prior OP_OpenEphemeral 
     ** instruction ended up not being needed, then change the OP_OpenEphemeral
@@ -100407,7 +100790,8 @@ SQLITE_PRIVATE int sqlite3Select(
 
     /* Use the standard inner loop. */
     selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, &sDistinct, pDest,
-                    pWInfo->iContinue, pWInfo->iBreak);
+                    sqlite3WhereContinueLabel(pWInfo),
+                    sqlite3WhereBreakLabel(pWInfo));
 
     /* End the database scan loop.
     */
@@ -100440,9 +100824,9 @@ SQLITE_PRIVATE int sqlite3Select(
       for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){
         pItem->iAlias = 0;
       }
-      if( p->nSelectRow>(double)100 ) p->nSelectRow = (double)100;
+      if( p->nSelectRow>100 ) p->nSelectRow = 100;
     }else{
-      p->nSelectRow = (double)1;
+      p->nSelectRow = 1;
     }
 
  
@@ -100522,9 +100906,10 @@ SQLITE_PRIVATE int sqlite3Select(
       ** in the right order to begin with.
       */
       sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
-      pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, 0, 0);
+      pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, 
+                                 WHERE_GROUPBY, 0);
       if( pWInfo==0 ) goto select_end;
-      if( pWInfo->nOBSat==pGroupBy->nExpr ){
+      if( sqlite3WhereIsOrdered(pWInfo) ){
         /* The optimizer is able to deliver rows in group by order so
         ** we do not have to sort.  The OP_OpenEphemeral table will be
         ** cancelled later because we still need to use the pKeyInfo
@@ -100805,8 +101190,8 @@ SQLITE_PRIVATE int sqlite3Select(
         }
         updateAccumulator(pParse, &sAggInfo);
         assert( pMinMax==0 || pMinMax->nExpr==1 );
-        if( pWInfo->nOBSat>0 ){
-          sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iBreak);
+        if( sqlite3WhereIsOrdered(pWInfo) ){
+          sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3WhereBreakLabel(pWInfo));
           VdbeComment((v, "%s() by index",
                 (flag==WHERE_ORDERBY_MIN?"min":"max")));
         }
@@ -102165,7 +102550,7 @@ SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect(
 /*
 ** This is called to code the required FOR EACH ROW triggers for an operation
 ** on table pTab. The operation to code triggers for (INSERT, UPDATE or DELETE)
-** is given by the op paramater. The tr_tm parameter determines whether the
+** is given by the op parameter. The tr_tm parameter determines whether the
 ** BEFORE or AFTER triggers are coded. If the operation is an UPDATE, then
 ** parameter pChanges is passed the list of columns being modified.
 **
@@ -102544,7 +102929,7 @@ SQLITE_PRIVATE void sqlite3Update(
   }
   for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
     int reg;
-    if( hasFK || chngRowid ){
+    if( hasFK || chngRowid || pIdx->pPartIdxWhere ){
       reg = ++pParse->nMem;
     }else{
       reg = 0;
@@ -102616,7 +103001,7 @@ SQLITE_PRIVATE void sqlite3Update(
       pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED, 0
   );
   if( pWInfo==0 ) goto update_cleanup;
-  okOnePass = pWInfo->okOnePass;
+  okOnePass = sqlite3WhereOkOnePass(pWInfo);
 
   /* Remember the rowid of every item to be updated.
   */
@@ -103085,7 +103470,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
     sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
     return SQLITE_ERROR;
   }
-  if( db->activeVdbeCnt>1 ){
+  if( db->nVdbeActive>1 ){
     sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress");
     return SQLITE_ERROR;
   }
@@ -104135,10 +104520,9 @@ static void callFinaliser(sqlite3 *db, int offset){
 ** array. Return the error code for the first error that occurs, or
 ** SQLITE_OK if all xSync operations are successful.
 **
-** Set *pzErrmsg to point to a buffer that should be released using 
-** sqlite3DbFree() containing an error message, if one is available.
+** If an error message is available, leave it in p->zErrMsg.
 */
-SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){
+SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, Vdbe *p){
   int i;
   int rc = SQLITE_OK;
   VTable **aVTrans = db->aVTrans;
@@ -104149,9 +104533,7 @@ SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){
     sqlite3_vtab *pVtab = aVTrans[i]->pVtab;
     if( pVtab && (x = pVtab->pModule->xSync)!=0 ){
       rc = x(pVtab);
-      sqlite3DbFree(db, *pzErrmsg);
-      *pzErrmsg = sqlite3DbStrDup(db, pVtab->zErrMsg);
-      sqlite3_free(pVtab->zErrMsg);
+      sqlite3VtabImportErrmsg(p, pVtab);
     }
   }
   db->aVTrans = aVTrans;
@@ -104453,18 +104835,186 @@ SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){
 #endif
 #if defined(SQLITE_DEBUG) \
     && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE))
-# define WHERETRACE(X)  if(sqlite3WhereTrace) sqlite3DebugPrintf X
+# define WHERETRACE(K,X)  if(sqlite3WhereTrace&(K)) sqlite3DebugPrintf X
+# define WHERETRACE_ENABLED 1
 #else
-# define WHERETRACE(X)
+# define WHERETRACE(K,X)
 #endif
 
-/* Forward reference
+/* Forward references
 */
 typedef struct WhereClause WhereClause;
 typedef struct WhereMaskSet WhereMaskSet;
 typedef struct WhereOrInfo WhereOrInfo;
 typedef struct WhereAndInfo WhereAndInfo;
-typedef struct WhereCost WhereCost;
+typedef struct WhereLevel WhereLevel;
+typedef struct WhereLoop WhereLoop;
+typedef struct WherePath WherePath;
+typedef struct WhereTerm WhereTerm;
+typedef struct WhereLoopBuilder WhereLoopBuilder;
+typedef struct WhereScan WhereScan;
+typedef struct WhereOrCost WhereOrCost;
+typedef struct WhereOrSet WhereOrSet;
+
+/*
+** Cost X is tracked as 10*log2(X) stored in a 16-bit integer.  The
+** maximum cost for ordinary tables is 64*(2**63) which becomes 6900.
+** (Virtual tables can return a larger cost, but let's assume they do not.)
+** So all costs can be stored in a 16-bit unsigned integer without risk
+** of overflow.
+**
+** Costs are estimates, so no effort is made to compute 10*log2(X) exactly.
+** Instead, a close estimate is used.  Any value of X<=1 is stored as 0.
+** X=2 is 10.  X=3 is 16.  X=1000 is 99. etc.
+**
+** The tool/wherecosttest.c source file implements a command-line program
+** that will convert WhereCosts to integers, convert integers to WhereCosts
+** and do addition and multiplication on WhereCost values.  The wherecosttest
+** command-line program is a useful utility to have around when working with
+** this module.
+*/
+typedef unsigned short int WhereCost;
+
+/*
+** This object contains information needed to implement a single nested
+** loop in WHERE clause.
+**
+** Contrast this object with WhereLoop.  This object describes the
+** implementation of the loop.  WhereLoop describes the algorithm.
+** This object contains a pointer to the WhereLoop algorithm as one of
+** its elements.
+**
+** The WhereInfo object contains a single instance of this object for
+** each term in the FROM clause (which is to say, for each of the
+** nested loops as implemented).  The order of WhereLevel objects determines
+** the loop nested order, with WhereInfo.a[0] being the outer loop and
+** WhereInfo.a[WhereInfo.nLevel-1] being the inner loop.
+*/
+struct WhereLevel {
+  int iLeftJoin;        /* Memory cell used to implement LEFT OUTER JOIN */
+  int iTabCur;          /* The VDBE cursor used to access the table */
+  int iIdxCur;          /* The VDBE cursor used to access pIdx */
+  int addrBrk;          /* Jump here to break out of the loop */
+  int addrNxt;          /* Jump here to start the next IN combination */
+  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 */
+  u8 iFrom;             /* Which entry in the FROM clause */
+  u8 op, p5;            /* Opcode and P5 of the opcode that ends the loop */
+  int p1, p2;           /* Operands of the opcode used to ends the loop */
+  union {               /* Information that depends on pWLoop->wsFlags */
+    struct {
+      int nIn;              /* Number of entries in aInLoop[] */
+      struct InLoop {
+        int iCur;              /* The VDBE cursor used by this IN operator */
+        int addrInTop;         /* Top of the IN loop */
+        u8 eEndLoopOp;         /* IN Loop terminator. OP_Next or OP_Prev */
+      } *aInLoop;           /* Information about each nested IN operator */
+    } in;                 /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */
+    Index *pCovidx;       /* Possible covering index for WHERE_MULTI_OR */
+  } u;
+  struct WhereLoop *pWLoop;  /* The selected WhereLoop object */
+};
+
+/*
+** Each instance of this object represents an algorithm for evaluating one
+** term of a join.  Every term of the FROM clause will have at least
+** one corresponding WhereLoop object (unless INDEXED BY constraints
+** prevent a query solution - which is an error) and many terms of the
+** FROM clause will have multiple WhereLoop objects, each describing a
+** potential way of implementing that FROM-clause term, together with
+** dependencies and cost estimates for using the chosen algorithm.
+**
+** Query planning consists of building up a collection of these WhereLoop
+** objects, then computing a particular sequence of WhereLoop objects, with
+** one WhereLoop object per FROM clause term, that satisfy all dependencies
+** and that minimize the overall cost.
+*/
+struct WhereLoop {
+  Bitmask prereq;       /* Bitmask of other loops that must run first */
+  Bitmask maskSelf;     /* Bitmask identifying table iTab */
+#ifdef SQLITE_DEBUG
+  char cId;             /* Symbolic ID of this loop for debugging use */
+#endif
+  u8 iTab;              /* Position in FROM clause of table for this loop */
+  u8 iSortIdx;          /* Sorting index number.  0==None */
+  WhereCost rSetup;     /* One-time setup cost (ex: create transient index) */
+  WhereCost rRun;       /* Cost of running each loop */
+  WhereCost nOut;       /* Estimated number of output rows */
+  union {
+    struct {               /* Information for internal btree tables */
+      int nEq;               /* Number of equality constraints */
+      Index *pIndex;         /* Index used, or NULL */
+    } btree;
+    struct {               /* Information for virtual tables */
+      int idxNum;            /* Index number */
+      u8 needFree;           /* True if sqlite3_free(idxStr) is needed */
+      u8 isOrdered;          /* True if satisfies ORDER BY */
+      u16 omitMask;          /* Terms that may be omitted */
+      char *idxStr;          /* Index identifier string */
+    } vtab;
+  } u;
+  u32 wsFlags;          /* WHERE_* flags describing the plan */
+  u16 nLTerm;           /* Number of entries in aLTerm[] */
+  /**** 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 */
+};
+
+/* This object holds the prerequisites and the cost of running a
+** subquery on one operand of an OR operator in the WHERE clause.
+** See WhereOrSet for additional information 
+*/
+struct WhereOrCost {
+  Bitmask prereq;     /* Prerequisites */
+  WhereCost rRun;     /* Cost of running this subquery */
+  WhereCost nOut;     /* Number of outputs for this subquery */
+};
+
+/* The WhereOrSet object holds a set of possible WhereOrCosts that
+** correspond to the subquery(s) of OR-clause processing.  Only the
+** best N_OR_COST elements are retained.
+*/
+#define N_OR_COST 3
+struct WhereOrSet {
+  u16 n;                      /* Number of valid a[] entries */
+  WhereOrCost a[N_OR_COST];   /* Set of best costs */
+};
+
+
+/* Forward declaration of methods */
+static int whereLoopResize(sqlite3*, WhereLoop*, int);
+
+/*
+** Each instance of this object holds a sequence of WhereLoop objects
+** that implement some or all of a query plan.
+**
+** Think of each WhereLoop object as a node in a graph with arcs
+** showing dependences and costs for travelling between nodes.  (That is
+** not a completely accurate description because WhereLoop costs are a
+** vector, not a scalar, and because dependences are many-to-one, not
+** one-to-one as are graph nodes.  But it is a useful visualization aid.)
+** Then a WherePath object is a path through the graph that visits some
+** or all of the WhereLoop objects once.
+**
+** The "solver" works by creating the N best WherePath objects of length
+** 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.
+*/
+struct WherePath {
+  Bitmask maskLoop;     /* Bitmask of all WhereLoop objects in this path */
+  Bitmask revLoop;      /* aLoop[]s that should be reversed for ORDER BY */
+  WhereCost nRow;       /* Estimated number of rows generated by this path */
+  WhereCost rCost;      /* Total cost of this path */
+  u8 isOrdered;         /* True if this path satisfies ORDER BY */
+  u8 isOrderedValid;    /* True if the isOrdered field is valid */
+  WhereLoop **aLoop;    /* Array of WhereLoop objects implementing this path */
+};
 
 /*
 ** The query generator uses an array of instances of this structure to
@@ -104492,9 +105042,9 @@ typedef struct WhereCost WhereCost;
 **
 **         (t1.X <op> <expr>) OR (t1.Y <op> <expr>) OR ....
 **
-** In this second case, wtFlag as the TERM_ORINFO set and eOperator==WO_OR
+** In this second case, wtFlag has the TERM_ORINFO bit set and eOperator==WO_OR
 ** and the WhereTerm.u.pOrInfo field points to auxiliary information that
-** is collected about the
+** is collected about the OR clause.
 **
 ** If a term in the WHERE clause does not match either of the two previous
 ** categories, then eOperator==0.  The WhereTerm.pExpr field is still set
@@ -104517,7 +105067,6 @@ typedef struct WhereCost WhereCost;
 ** in prereqRight and prereqAll.  The default is 64 bits, hence SQLite
 ** is only able to process joins with 64 or fewer tables.
 */
-typedef struct WhereTerm WhereTerm;
 struct WhereTerm {
   Expr *pExpr;            /* Pointer to the subexpression that is this term */
   int iParent;            /* Disable pWC->a[iParent] when this term disabled */
@@ -104552,6 +105101,22 @@ struct WhereTerm {
 #endif
 
 /*
+** An instance of the WhereScan object is used as an iterator for locating
+** terms in the WHERE clause that are useful to the query planner.
+*/
+struct WhereScan {
+  WhereClause *pOrigWC;      /* Original, innermost WhereClause */
+  WhereClause *pWC;          /* WhereClause currently being scanned */
+  char *zCollName;           /* Required collating sequence, if not NULL */
+  char idxaff;               /* Must match this affinity, if zCollName!=NULL */
+  unsigned char nEquiv;      /* Number of entries in aEquiv[] */
+  unsigned char iEquiv;      /* Next unused slot in aEquiv[] */
+  u32 opMask;                /* Acceptable operators */
+  int k;                     /* Resume scanning at this->pWC->a[this->k] */
+  int aEquiv[22];            /* Cursor,Column pairs for equivalence classes */
+};
+
+/*
 ** An instance of the following structure holds all information about a
 ** WHERE clause.  Mostly this is a container for one or more WhereTerms.
 **
@@ -104564,11 +105129,9 @@ struct WhereTerm {
 ** subclauses points to the WhereClause object for the whole clause.
 */
 struct WhereClause {
-  Parse *pParse;           /* The parser context */
-  WhereMaskSet *pMaskSet;  /* Mapping of table cursor numbers to bitmasks */
+  WhereInfo *pWInfo;       /* WHERE clause processing context */
   WhereClause *pOuter;     /* Outer conjunction */
   u8 op;                   /* Split operator.  TK_AND or TK_OR */
-  u16 wctrlFlags;          /* Might include WHERE_AND_ONLY */
   int nTerm;               /* Number of terms */
   int nSlot;               /* Number of entries in a[] */
   WhereTerm *a;            /* Each a[] describes a term of the WHERE cluase */
@@ -104628,19 +105191,55 @@ struct WhereMaskSet {
 };
 
 /*
-** A WhereCost object records a lookup strategy and the estimated
-** cost of pursuing that strategy.
+** This object is a convenience wrapper holding all information needed
+** to construct WhereLoop objects for a particular query.
 */
-struct WhereCost {
-  WherePlan plan;    /* The lookup strategy */
-  double rCost;      /* Overall cost of pursuing this search strategy */
-  Bitmask used;      /* Bitmask of cursors used by this plan */
+struct WhereLoopBuilder {
+  WhereInfo *pWInfo;        /* Information about this WHERE */
+  WhereClause *pWC;         /* WHERE clause terms */
+  ExprList *pOrderBy;       /* ORDER BY clause */
+  WhereLoop *pNew;          /* Template WhereLoop */
+  WhereOrSet *pOrSet;       /* Record best loops here, if not NULL */
+};
+
+/*
+** The WHERE clause processing routine has two halves.  The
+** first part does the start of the WHERE loop and the second
+** half does the tail of the WHERE loop.  An instance of
+** this structure is returned by the first half and passed
+** into the second half to give some continuity.
+**
+** An instance of this object holds the complete state of the query
+** planner.
+*/
+struct WhereInfo {
+  Parse *pParse;            /* Parsing and code generating context */
+  SrcList *pTabList;        /* List of tables in the join */
+  ExprList *pOrderBy;       /* The ORDER BY clause or NULL */
+  ExprList *pResultSet;     /* Result set. DISTINCT operates on these */
+  WhereLoop *pLoops;        /* List of all WhereLoop objects */
+  Bitmask revMask;          /* Mask of ORDER BY terms that need reversing */
+  WhereCost nRowOut;        /* Estimated number of output rows */
+  u16 wctrlFlags;           /* Flags originally passed to sqlite3WhereBegin() */
+  u8 bOBSat;                /* ORDER BY satisfied by indices */
+  u8 okOnePass;             /* Ok to use one-pass algorithm for UPDATE/DELETE */
+  u8 untestedTerms;         /* Not all WHERE terms resolved by outer loop */
+  u8 eDistinct;             /* One of the WHERE_DISTINCT_* values below */
+  u8 nLevel;                /* Number of nested loop */
+  int iTop;                 /* The very beginning of the WHERE loop */
+  int iContinue;            /* Jump here to continue with next record */
+  int iBreak;               /* Jump here to break out of the loop */
+  int savedNQueryLoop;      /* pParse->nQueryLoop outside the WHERE loop */
+  WhereMaskSet sMaskSet;    /* Map cursor numbers to bitmasks */
+  WhereClause sWC;          /* Decomposition of the WHERE clause */
+  WhereLevel a[1];          /* Information about each nest loop in WHERE */
 };
 
 /*
-** Bitmasks for the operators that indices are able to exploit.  An
+** Bitmasks for the operators on WhereTerm objects.  These are all
+** operators that are of interest to the query planner.  An
 ** OR-ed combination of these values can be used when searching for
-** terms in the where clause.
+** particular WhereTerms within a WhereClause.
 */
 #define WO_IN     0x001
 #define WO_EQ     0x002
@@ -104659,74 +105258,136 @@ struct WhereCost {
 #define WO_SINGLE 0x0ff       /* Mask of all non-compound WO_* values */
 
 /*
-** Value for wsFlags returned by bestIndex() and stored in
-** WhereLevel.wsFlags.  These flags determine which search
-** strategies are appropriate.
-**
-** The least significant 12 bits is reserved as a mask for WO_ values above.
-** The WhereLevel.wsFlags field is usually set to WO_IN|WO_EQ|WO_ISNULL.
-** But if the table is the right table of a left join, WhereLevel.wsFlags
-** is set to WO_IN|WO_EQ.  The WhereLevel.wsFlags field can then be used as
-** the "op" parameter to findTerm when we are resolving equality constraints.
-** ISNULL constraints will then not be used on the right table of a left
-** join.  Tickets #2177 and #2189.
-*/
-#define WHERE_ROWID_EQ     0x00001000  /* rowid=EXPR or rowid IN (...) */
-#define WHERE_ROWID_RANGE  0x00002000  /* rowid<EXPR and/or rowid>EXPR */
-#define WHERE_COLUMN_EQ    0x00010000  /* x=EXPR or x IN (...) or x IS NULL */
-#define WHERE_COLUMN_RANGE 0x00020000  /* x<EXPR and/or x>EXPR */
-#define WHERE_COLUMN_IN    0x00040000  /* x IN (...) */
-#define WHERE_COLUMN_NULL  0x00080000  /* x IS NULL */
-#define WHERE_INDEXED      0x000f0000  /* Anything that uses an index */
-#define WHERE_NOT_FULLSCAN 0x100f3000  /* Does not do a full table scan */
-#define WHERE_IN_ABLE      0x080f1000  /* Able to support an IN operator */
-#define WHERE_TOP_LIMIT    0x00100000  /* x<EXPR or x<=EXPR constraint */
-#define WHERE_BTM_LIMIT    0x00200000  /* x>EXPR or x>=EXPR constraint */
-#define WHERE_BOTH_LIMIT   0x00300000  /* Both x>EXPR and x<EXPR */
-#define WHERE_IDX_ONLY     0x00400000  /* Use index only - omit table */
-#define WHERE_ORDERED      0x00800000  /* Output will appear in correct order */
-#define WHERE_REVERSE      0x01000000  /* Scan in reverse order */
-#define WHERE_UNIQUE       0x02000000  /* Selects no more than one row */
-#define WHERE_ALL_UNIQUE   0x04000000  /* This and all prior have one row */
-#define WHERE_OB_UNIQUE    0x00004000  /* Values in ORDER BY columns are 
-                                       ** different for every output row */
-#define WHERE_VIRTUALTABLE 0x08000000  /* Use virtual-table processing */
-#define WHERE_MULTI_OR     0x10000000  /* OR using multiple indices */
-#define WHERE_TEMP_INDEX   0x20000000  /* Uses an ephemeral index */
-#define WHERE_DISTINCT     0x40000000  /* Correct order for DISTINCT */
-#define WHERE_COVER_SCAN   0x80000000  /* Full scan of a covering index */
-
-/*
-** This module contains many separate subroutines that work together to
-** find the best indices to use for accessing a particular table in a query.
-** An instance of the following structure holds context information about the
-** index search so that it can be more easily passed between the various
-** routines.
+** These are definitions of bits in the WhereLoop.wsFlags field.
+** The particular combination of bits in each WhereLoop help to
+** determine the algorithm that WhereLoop represents.
+*/
+#define WHERE_COLUMN_EQ    0x00000001  /* x=EXPR */
+#define WHERE_COLUMN_RANGE 0x00000002  /* x<EXPR and/or x>EXPR */
+#define WHERE_COLUMN_IN    0x00000004  /* x IN (...) */
+#define WHERE_COLUMN_NULL  0x00000008  /* x IS NULL */
+#define WHERE_CONSTRAINT   0x0000000f  /* Any of the WHERE_COLUMN_xxx values */
+#define WHERE_TOP_LIMIT    0x00000010  /* x<EXPR or x<=EXPR constraint */
+#define WHERE_BTM_LIMIT    0x00000020  /* x>EXPR or x>=EXPR constraint */
+#define WHERE_BOTH_LIMIT   0x00000030  /* Both x>EXPR and x<EXPR */
+#define WHERE_IDX_ONLY     0x00000040  /* Use index only - omit table */
+#define WHERE_IPK          0x00000100  /* x is the INTEGER PRIMARY KEY */
+#define WHERE_INDEXED      0x00000200  /* WhereLoop.u.btree.pIndex is valid */
+#define WHERE_VIRTUALTABLE 0x00000400  /* WhereLoop.u.vtab is valid */
+#define WHERE_IN_ABLE      0x00000800  /* Able to support an IN operator */
+#define WHERE_ONEROW       0x00001000  /* Selects no more than one row */
+#define WHERE_MULTI_OR     0x00002000  /* OR using multiple indices */
+#define WHERE_AUTO_INDEX   0x00004000  /* Uses an ephemeral index */
+
+
+/* Convert a WhereCost value (10 times log2(X)) into its integer value X.
+** A rough approximation is used.  The value returned is not exact.
+*/
+static u64 whereCostToInt(WhereCost x){
+  u64 n;
+  if( x<10 ) return 1;
+  n = x%10;
+  x /= 10;
+  if( n>=5 ) n -= 2;
+  else if( n>=1 ) n -= 1;
+  if( x>=3 ) return (n+8)<<(x-3);
+  return (n+8)>>(3-x);
+}
+
+/*
+** Return the estimated number of output rows from a WHERE clause
 */
-typedef struct WhereBestIdx WhereBestIdx;
-struct WhereBestIdx {
-  Parse *pParse;                  /* Parser context */
-  WhereClause *pWC;               /* The WHERE clause */
-  struct SrcList_item *pSrc;      /* The FROM clause term to search */
-  Bitmask notReady;               /* Mask of cursors not available */
-  Bitmask notValid;               /* Cursors not available for any purpose */
-  ExprList *pOrderBy;             /* The ORDER BY clause */
-  ExprList *pDistinct;            /* The select-list if query is DISTINCT */
-  sqlite3_index_info **ppIdxInfo; /* Index information passed to xBestIndex */
-  int i, n;                       /* Which loop is being coded; # of loops */
-  WhereLevel *aLevel;             /* Info about outer loops */
-  WhereCost cost;                 /* Lowest cost query plan */
-};
+SQLITE_PRIVATE u64 sqlite3WhereOutputRowCount(WhereInfo *pWInfo){
+  return whereCostToInt(pWInfo->nRowOut);
+}
 
 /*
-** Return TRUE if the probe cost is less than the baseline cost
+** Return one of the WHERE_DISTINCT_xxxxx values to indicate how this
+** WHERE clause returns outputs for DISTINCT processing.
 */
-static int compareCost(const WhereCost *pProbe, const WhereCost *pBaseline){
-  if( pProbe->rCost<pBaseline->rCost ) return 1;
-  if( pProbe->rCost>pBaseline->rCost ) return 0;
-  if( pProbe->plan.nOBSat>pBaseline->plan.nOBSat ) return 1;
-  if( pProbe->plan.nRow<pBaseline->plan.nRow ) return 1;
-  return 0;
+SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo *pWInfo){
+  return pWInfo->eDistinct;
+}
+
+/*
+** Return TRUE if the WHERE clause returns rows in ORDER BY order.
+** Return FALSE if the output needs to be sorted.
+*/
+SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo *pWInfo){
+  return pWInfo->bOBSat!=0;
+}
+
+/*
+** Return the VDBE address or label to jump to in order to continue
+** immediately with the next row of a WHERE clause.
+*/
+SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo *pWInfo){
+  return pWInfo->iContinue;
+}
+
+/*
+** Return the VDBE address or label to jump to in order to break
+** out of a WHERE loop.
+*/
+SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo *pWInfo){
+  return pWInfo->iBreak;
+}
+
+/*
+** Return TRUE if an UPDATE or DELETE statement can operate directly on
+** the rowids returned by a WHERE clause.  Return FALSE if doing an
+** UPDATE or DELETE might change subsequent WHERE clause results.
+*/
+SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo *pWInfo){
+  return pWInfo->okOnePass;
+}
+
+/*
+** Move the content of pSrc into pDest
+*/
+static void whereOrMove(WhereOrSet *pDest, WhereOrSet *pSrc){
+  pDest->n = pSrc->n;
+  memcpy(pDest->a, pSrc->a, pDest->n*sizeof(pDest->a[0]));
+}
+
+/*
+** Try to insert a new prerequisite/cost entry into the WhereOrSet pSet.
+**
+** The new entry might overwrite an existing entry, or it might be
+** appended, or it might be discarded.  Do whatever is the right thing
+** so that pSet keeps the N_OR_COST best entries seen so far.
+*/
+static int whereOrInsert(
+  WhereOrSet *pSet,      /* The WhereOrSet to be updated */
+  Bitmask prereq,        /* Prerequisites of the new entry */
+  WhereCost rRun,        /* Run-cost of the new entry */
+  WhereCost nOut         /* Number of outputs for the new entry */
+){
+  u16 i;
+  WhereOrCost *p;
+  for(i=pSet->n, p=pSet->a; i>0; i--, p++){
+    if( rRun<=p->rRun && (prereq & p->prereq)==prereq ){
+      goto whereOrInsert_done;
+    }
+    if( p->rRun<=rRun && (p->prereq & prereq)==p->prereq ){
+      return 0;
+    }
+  }
+  if( pSet->n<N_OR_COST ){
+    p = &pSet->a[pSet->n++];
+    p->nOut = nOut;
+  }else{
+    p = pSet->a;
+    for(i=1; i<pSet->n; i++){
+      if( p->rRun>pSet->a[i].rRun ) p = pSet->a + i;
+    }
+    if( p->rRun<=rRun ) return 0;
+  }
+whereOrInsert_done:
+  p->prereq = prereq;
+  p->rRun = rRun;
+  if( p->nOut>nOut ) p->nOut = nOut;
+  return 1;
 }
 
 /*
@@ -104734,17 +105395,13 @@ static int compareCost(const WhereCost *pProbe, const WhereCost *pBaseline){
 */
 static void whereClauseInit(
   WhereClause *pWC,        /* The WhereClause to be initialized */
-  Parse *pParse,           /* The parsing context */
-  WhereMaskSet *pMaskSet,  /* Mapping from table cursor numbers to bitmasks */
-  u16 wctrlFlags           /* Might include WHERE_AND_ONLY */
+  WhereInfo *pWInfo        /* The WHERE processing context */
 ){
-  pWC->pParse = pParse;
-  pWC->pMaskSet = pMaskSet;
+  pWC->pWInfo = pWInfo;
   pWC->pOuter = 0;
   pWC->nTerm = 0;
   pWC->nSlot = ArraySize(pWC->aStatic);
   pWC->a = pWC->aStatic;
-  pWC->wctrlFlags = wctrlFlags;
 }
 
 /* Forward reference */
@@ -104773,7 +105430,7 @@ static void whereAndInfoDelete(sqlite3 *db, WhereAndInfo *p){
 static void whereClauseClear(WhereClause *pWC){
   int i;
   WhereTerm *a;
-  sqlite3 *db = pWC->pParse->db;
+  sqlite3 *db = pWC->pWInfo->pParse->db;
   for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){
     if( a->wtFlags & TERM_DYNAMIC ){
       sqlite3ExprDelete(db, a->pExpr);
@@ -104811,10 +105468,10 @@ static void whereClauseClear(WhereClause *pWC){
 static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
   WhereTerm *pTerm;
   int idx;
-  testcase( wtFlags & TERM_VIRTUAL );  /* EV: R-00211-15100 */
+  testcase( wtFlags & TERM_VIRTUAL );
   if( pWC->nTerm>=pWC->nSlot ){
     WhereTerm *pOld = pWC->a;
-    sqlite3 *db = pWC->pParse->db;
+    sqlite3 *db = pWC->pWInfo->pParse->db;
     pWC->a = sqlite3DbMallocRaw(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
     if( pWC->a==0 ){
       if( wtFlags & TERM_DYNAMIC ){
@@ -104854,8 +105511,8 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
 ** the WhereClause.a[] array.  The slot[] array grows as needed to contain
 ** all terms of the WHERE clause.
 */
-static void whereSplit(WhereClause *pWC, Expr *pExpr, int op){
-  pWC->op = (u8)op;
+static void whereSplit(WhereClause *pWC, Expr *pExpr, u8 op){
+  pWC->op = op;
   if( pExpr==0 ) return;
   if( pExpr->op!=op ){
     whereClauseInsert(pWC, pExpr, 0);
@@ -104866,9 +105523,9 @@ static void whereSplit(WhereClause *pWC, Expr *pExpr, int op){
 }
 
 /*
-** Initialize an expression mask set (a WhereMaskSet object)
+** Initialize a WhereMaskSet object
 */
-#define initMaskSet(P)  memset(P, 0, sizeof(*P))
+#define initMaskSet(P)  (P)->n=0
 
 /*
 ** Return the bitmask for the given cursor number.  Return 0 if
@@ -104879,7 +105536,7 @@ static Bitmask getMask(WhereMaskSet *pMaskSet, int iCursor){
   assert( pMaskSet->n<=(int)sizeof(Bitmask)*8 );
   for(i=0; i<pMaskSet->n; i++){
     if( pMaskSet->ix[i]==iCursor ){
-      return ((Bitmask)1)<<i;
+      return MASKBIT(i);
     }
   }
   return 0;
@@ -104899,18 +105556,9 @@ static void createMask(WhereMaskSet *pMaskSet, int iCursor){
 }
 
 /*
-** This routine walks (recursively) an expression tree and generates
+** These routines walk (recursively) an expression tree and generate
 ** a bitmask indicating which tables are used in that expression
 ** tree.
-**
-** In order for this routine to work, the calling function must have
-** previously invoked sqlite3ResolveExprNames() on the expression.  See
-** the header comment on that routine for additional information.
-** The sqlite3ResolveExprNames() routines looks for column names and
-** sets their opcodes to TK_COLUMN and their Expr.iTable fields to
-** the VDBE cursor number of the table.  This routine just has to
-** translate the cursor numbers into bitmask values and OR all
-** the bitmasks together.
 */
 static Bitmask exprListTableUsage(WhereMaskSet*, ExprList*);
 static Bitmask exprSelectTableUsage(WhereMaskSet*, Select*);
@@ -104964,14 +105612,7 @@ static Bitmask exprSelectTableUsage(WhereMaskSet *pMaskSet, Select *pS){
 /*
 ** Return TRUE if the given operator is one of the operators that is
 ** allowed for an indexable WHERE clause term.  The allowed operators are
-** "=", "<", ">", "<=", ">=", and "IN".
-**
-** IMPLEMENTATION-OF: R-59926-26393 To be usable by an index a term must be
-** of one of the following forms: column = expression column > expression
-** column >= expression column < expression column <= expression
-** expression = column expression > column expression >= column
-** expression < column expression <= column column IN
-** (expression-list) column IN (subquery) column IS NULL
+** "=", "<", ">", "<=", ">=", "IN", and "IS NULL"
 */
 static int allowedOp(int op){
   assert( TK_GT>TK_EQ && TK_GT<TK_GE );
@@ -104991,10 +105632,9 @@ static int allowedOp(int op){
 ** are converted into "Y op X".
 **
 ** If left/right precedence rules come into play when determining the
-** collating
-** side of the comparison, it remains associated with the same side after
-** the commutation. So "Y collate NOCASE op X" becomes 
-** "X op Y". This is because any collation sequence on
+** collating sequence, then COLLATE operators are adjusted to ensure
+** that the collating sequence does not change.  For example:
+** "Y collate NOCASE op X" becomes "X op Y" because any collation sequence on
 ** the left hand side of a comparison overrides any collation sequence 
 ** attached to the right. For the same reason the EP_Collate flag
 ** is not commuted.
@@ -105052,6 +105692,130 @@ static u16 operatorMask(int op){
 }
 
 /*
+** Advance to the next WhereTerm that matches according to the criteria
+** established when the pScan object was initialized by whereScanInit().
+** Return NULL if there are no more matching WhereTerms.
+*/
+static WhereTerm *whereScanNext(WhereScan *pScan){
+  int iCur;            /* The cursor on the LHS of the term */
+  int iColumn;         /* The column on the LHS of the term.  -1 for IPK */
+  Expr *pX;            /* An expression being tested */
+  WhereClause *pWC;    /* Shorthand for pScan->pWC */
+  WhereTerm *pTerm;    /* The term being tested */
+  int k = pScan->k;    /* Where to start scanning */
+
+  while( pScan->iEquiv<=pScan->nEquiv ){
+    iCur = pScan->aEquiv[pScan->iEquiv-2];
+    iColumn = pScan->aEquiv[pScan->iEquiv-1];
+    while( (pWC = pScan->pWC)!=0 ){
+      for(pTerm=pWC->a+k; k<pWC->nTerm; k++, pTerm++){
+        if( pTerm->leftCursor==iCur && pTerm->u.leftColumn==iColumn ){
+          if( (pTerm->eOperator & WO_EQUIV)!=0
+           && pScan->nEquiv<ArraySize(pScan->aEquiv)
+          ){
+            int j;
+            pX = sqlite3ExprSkipCollate(pTerm->pExpr->pRight);
+            assert( pX->op==TK_COLUMN );
+            for(j=0; j<pScan->nEquiv; j+=2){
+              if( pScan->aEquiv[j]==pX->iTable
+               && pScan->aEquiv[j+1]==pX->iColumn ){
+                  break;
+              }
+            }
+            if( j==pScan->nEquiv ){
+              pScan->aEquiv[j] = pX->iTable;
+              pScan->aEquiv[j+1] = pX->iColumn;
+              pScan->nEquiv += 2;
+            }
+          }
+          if( (pTerm->eOperator & pScan->opMask)!=0 ){
+            /* Verify the affinity and collating sequence match */
+            if( pScan->zCollName && (pTerm->eOperator & WO_ISNULL)==0 ){
+              CollSeq *pColl;
+              Parse *pParse = pWC->pWInfo->pParse;
+              pX = pTerm->pExpr;
+              if( !sqlite3IndexAffinityOk(pX, pScan->idxaff) ){
+                continue;
+              }
+              assert(pX->pLeft);
+              pColl = sqlite3BinaryCompareCollSeq(pParse,
+                                                  pX->pLeft, pX->pRight);
+              if( pColl==0 ) pColl = pParse->db->pDfltColl;
+              if( sqlite3StrICmp(pColl->zName, pScan->zCollName) ){
+                continue;
+              }
+            }
+            if( (pTerm->eOperator & WO_EQ)!=0
+             && (pX = pTerm->pExpr->pRight)->op==TK_COLUMN
+             && pX->iTable==pScan->aEquiv[0]
+             && pX->iColumn==pScan->aEquiv[1]
+            ){
+              continue;
+            }
+            pScan->k = k+1;
+            return pTerm;
+          }
+        }
+      }
+      pScan->pWC = pScan->pWC->pOuter;
+      k = 0;
+    }
+    pScan->pWC = pScan->pOrigWC;
+    k = 0;
+    pScan->iEquiv += 2;
+  }
+  return 0;
+}
+
+/*
+** Initialize a WHERE clause scanner object.  Return a pointer to the
+** first match.  Return NULL if there are no matches.
+**
+** The scanner will be searching the WHERE clause pWC.  It will look
+** for terms of the form "X <op> <expr>" where X is column iColumn of table
+** iCur.  The <op> must be one of the operators described by opMask.
+**
+** If the search is for X and the WHERE clause contains terms of the
+** form X=Y then this routine might also return terms of the form
+** "Y <op> <expr>".  The number of levels of transitivity is limited,
+** but is enough to handle most commonly occurring SQL statements.
+**
+** If X is not the INTEGER PRIMARY KEY then X must be compatible with
+** index pIdx.
+*/
+static WhereTerm *whereScanInit(
+  WhereScan *pScan,       /* The WhereScan object being initialized */
+  WhereClause *pWC,       /* The WHERE clause to be scanned */
+  int iCur,               /* Cursor to scan for */
+  int iColumn,            /* Column to scan for */
+  u32 opMask,             /* Operator(s) to scan for */
+  Index *pIdx             /* Must be compatible with this index */
+){
+  int j;
+
+  /* memset(pScan, 0, sizeof(*pScan)); */
+  pScan->pOrigWC = pWC;
+  pScan->pWC = pWC;
+  if( pIdx && iColumn>=0 ){
+    pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
+    for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
+      if( NEVER(j>=pIdx->nColumn) ) return 0;
+    }
+    pScan->zCollName = pIdx->azColl[j];
+  }else{
+    pScan->idxaff = 0;
+    pScan->zCollName = 0;
+  }
+  pScan->opMask = opMask;
+  pScan->k = 0;
+  pScan->aEquiv[0] = iCur;
+  pScan->aEquiv[1] = iColumn;
+  pScan->nEquiv = 2;
+  pScan->iEquiv = 2;
+  return whereScanNext(pScan);
+}
+
+/*
 ** Search for a term in the WHERE clause that is of the form "X <op> <expr>"
 ** where X is a reference to the iColumn of table iCur and <op> is one of
 ** the WO_xx operator codes specified by the op parameter.
@@ -105082,84 +105846,20 @@ static WhereTerm *findTerm(
   u32 op,               /* Mask of WO_xx values describing operator */
   Index *pIdx           /* Must be compatible with this index, if not NULL */
 ){
-  WhereTerm *pTerm;            /* Term being examined as possible result */
-  WhereTerm *pResult = 0;      /* The answer to return */
-  WhereClause *pWCOrig = pWC;  /* Original pWC value */
-  int j, k;                    /* Loop counters */
-  Expr *pX;                /* Pointer to an expression */
-  Parse *pParse;           /* Parsing context */
-  int iOrigCol = iColumn;  /* Original value of iColumn */
-  int nEquiv = 2;          /* Number of entires in aEquiv[] */
-  int iEquiv = 2;          /* Number of entries of aEquiv[] processed so far */
-  int aEquiv[22];          /* iCur,iColumn and up to 10 other equivalents */
-
-  assert( iCur>=0 );
-  aEquiv[0] = iCur;
-  aEquiv[1] = iColumn;
-  for(;;){
-    for(pWC=pWCOrig; pWC; pWC=pWC->pOuter){
-      for(pTerm=pWC->a, k=pWC->nTerm; k; k--, pTerm++){
-        if( pTerm->leftCursor==iCur
-          && pTerm->u.leftColumn==iColumn
-        ){
-          if( (pTerm->prereqRight & notReady)==0
-           && (pTerm->eOperator & op & WO_ALL)!=0
-          ){
-            if( iOrigCol>=0 && pIdx && (pTerm->eOperator & WO_ISNULL)==0 ){
-              CollSeq *pColl;
-              char idxaff;
-      
-              pX = pTerm->pExpr;
-              pParse = pWC->pParse;
-              idxaff = pIdx->pTable->aCol[iOrigCol].affinity;
-              if( !sqlite3IndexAffinityOk(pX, idxaff) ){
-                continue;
-              }
-      
-              /* Figure out the collation sequence required from an index for
-              ** it to be useful for optimising expression pX. Store this
-              ** value in variable pColl.
-              */
-              assert(pX->pLeft);
-              pColl = sqlite3BinaryCompareCollSeq(pParse,pX->pLeft,pX->pRight);
-              if( pColl==0 ) pColl = pParse->db->pDfltColl;
-      
-              for(j=0; pIdx->aiColumn[j]!=iOrigCol; j++){
-                if( NEVER(j>=pIdx->nColumn) ) return 0;
-              }
-              if( sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ){
-                continue;
-              }
-            }
-            if( pTerm->prereqRight==0 && (pTerm->eOperator&WO_EQ)!=0 ){
-              pResult = pTerm;
-              goto findTerm_success;
-            }else if( pResult==0 ){
-              pResult = pTerm;
-            }
-          }
-          if( (pTerm->eOperator & WO_EQUIV)!=0
-           && nEquiv<ArraySize(aEquiv)
-          ){
-            pX = sqlite3ExprSkipCollate(pTerm->pExpr->pRight);
-            assert( pX->op==TK_COLUMN );
-            for(j=0; j<nEquiv; j+=2){
-              if( aEquiv[j]==pX->iTable && aEquiv[j+1]==pX->iColumn ) break;
-            }
-            if( j==nEquiv ){
-              aEquiv[j] = pX->iTable;
-              aEquiv[j+1] = pX->iColumn;
-              nEquiv += 2;
-            }
-          }
-        }
+  WhereTerm *pResult = 0;
+  WhereTerm *p;
+  WhereScan scan;
+
+  p = whereScanInit(&scan, pWC, iCur, iColumn, op, pIdx);
+  while( p ){
+    if( (p->prereqRight & notReady)==0 ){
+      if( p->prereqRight==0 && (p->eOperator&WO_EQ)!=0 ){
+        return p;
       }
+      if( pResult==0 ) pResult = p;
     }
-    if( iEquiv>=nEquiv ) break;
-    iCur = aEquiv[iEquiv++];
-    iColumn = aEquiv[iEquiv++];
+    p = whereScanNext(&scan);
   }
-findTerm_success:
   return pResult;
 }
 
@@ -105168,8 +105868,6 @@ static void exprAnalyze(SrcList*, WhereClause*, int);
 
 /*
 ** Call exprAnalyze on all terms in a WHERE clause.  
-**
-**
 */
 static void exprAnalyzeAll(
   SrcList *pTabList,       /* the FROM clause */
@@ -105233,7 +105931,7 @@ static int isLikeOrGlob(
   if( op==TK_VARIABLE ){
     Vdbe *pReprepare = pParse->pReprepare;
     int iCol = pRight->iColumn;
-    pVal = sqlite3VdbeGetValue(pReprepare, iCol, SQLITE_AFF_NONE);
+    pVal = sqlite3VdbeGetBoundValue(pReprepare, iCol, SQLITE_AFF_NONE);
     if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){
       z = (char *)sqlite3_value_text(pVal);
     }
@@ -105315,8 +106013,10 @@ static int isMatchOfColumn(
 ** a join, then transfer the appropriate markings over to derived.
 */
 static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
-  pDerived->flags |= pBase->flags & EP_FromJoin;
-  pDerived->iRightJoinTable = pBase->iRightJoinTable;
+  if( pDerived ){
+    pDerived->flags |= pBase->flags & EP_FromJoin;
+    pDerived->iRightJoinTable = pBase->iRightJoinTable;
+  }
 }
 
 #if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
@@ -105375,10 +106075,10 @@ static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
 ** From another point of view, "indexable" means that the subterm could
 ** potentially be used with an index if an appropriate index exists.
 ** This analysis does not consider whether or not the index exists; that
-** is something the bestIndex() routine will determine.  This analysis
-** only looks at whether subterms appropriate for indexing exist.
+** is decided elsewhere.  This analysis only looks at whether subterms
+** appropriate for indexing exist.
 **
-** All examples A through E above all satisfy case 2.  But if a term
+** 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
 ** always prefer case 1, so in that case we pretend that case 2 is not
 ** satisfied.
@@ -105401,11 +106101,11 @@ static void exprAnalyzeOrTerm(
   WhereClause *pWC,         /* the complete WHERE clause */
   int idxTerm               /* Index of the OR-term to be analyzed */
 ){
-  Parse *pParse = pWC->pParse;            /* Parser context */
+  WhereInfo *pWInfo = pWC->pWInfo;        /* WHERE clause processing context */
+  Parse *pParse = pWInfo->pParse;         /* Parser context */
   sqlite3 *db = pParse->db;               /* Database connection */
   WhereTerm *pTerm = &pWC->a[idxTerm];    /* The term to be analyzed */
   Expr *pExpr = pTerm->pExpr;             /* The expression of the term */
-  WhereMaskSet *pMaskSet = pWC->pMaskSet; /* Table use masks */
   int i;                                  /* Loop counters */
   WhereClause *pOrWc;       /* Breakup of pTerm into subterms */
   WhereTerm *pOrTerm;       /* A Sub-term within the pOrWc */
@@ -105424,7 +106124,7 @@ static void exprAnalyzeOrTerm(
   if( pOrInfo==0 ) return;
   pTerm->wtFlags |= TERM_ORINFO;
   pOrWc = &pOrInfo->wc;
-  whereClauseInit(pOrWc, pWC->pParse, pMaskSet, pWC->wctrlFlags);
+  whereClauseInit(pOrWc, pWInfo);
   whereSplit(pOrWc, pExpr, TK_OR);
   exprAnalyzeAll(pSrc, pOrWc);
   if( db->mallocFailed ) return;
@@ -105450,7 +106150,7 @@ static void exprAnalyzeOrTerm(
         pOrTerm->wtFlags |= TERM_ANDINFO;
         pOrTerm->eOperator = WO_AND;
         pAndWC = &pAndInfo->wc;
-        whereClauseInit(pAndWC, pWC->pParse, pMaskSet, pWC->wctrlFlags);
+        whereClauseInit(pAndWC, pWC->pWInfo);
         whereSplit(pAndWC, pOrTerm->pExpr, TK_AND);
         exprAnalyzeAll(pSrc, pAndWC);
         pAndWC->pOuter = pWC;
@@ -105459,7 +106159,7 @@ static void exprAnalyzeOrTerm(
           for(j=0, pAndTerm=pAndWC->a; j<pAndWC->nTerm; j++, pAndTerm++){
             assert( pAndTerm->pExpr );
             if( allowedOp(pAndTerm->pExpr->op) ){
-              b |= getMask(pMaskSet, pAndTerm->leftCursor);
+              b |= getMask(&pWInfo->sMaskSet, pAndTerm->leftCursor);
             }
           }
         }
@@ -105470,10 +106170,10 @@ static void exprAnalyzeOrTerm(
       ** corresponding TERM_VIRTUAL term */
     }else{
       Bitmask b;
-      b = getMask(pMaskSet, pOrTerm->leftCursor);
+      b = getMask(&pWInfo->sMaskSet, pOrTerm->leftCursor);
       if( pOrTerm->wtFlags & TERM_VIRTUAL ){
         WhereTerm *pOther = &pOrWc->a[pOrTerm->iParent];
-        b |= getMask(pMaskSet, pOther->leftCursor);
+        b |= getMask(&pWInfo->sMaskSet, pOther->leftCursor);
       }
       indexable &= b;
       if( (pOrTerm->eOperator & WO_EQ)==0 ){
@@ -105535,7 +106235,7 @@ static void exprAnalyzeOrTerm(
           assert( j==1 );
           continue;
         }
-        if( (chngToIN & getMask(pMaskSet, pOrTerm->leftCursor))==0 ){
+        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
           ** or follwed by an inverted copy (t2.b==t1.a).  Skip this term 
@@ -105554,7 +106254,7 @@ static void exprAnalyzeOrTerm(
         ** on the second iteration */
         assert( j==1 );
         assert( IsPowerOfTwo(chngToIN) );
-        assert( chngToIN==getMask(pMaskSet, iCursor) );
+        assert( chngToIN==getMask(&pWInfo->sMaskSet, iCursor) );
         break;
       }
       testcase( j==1 );
@@ -105588,8 +106288,6 @@ static void exprAnalyzeOrTerm(
     /* At this point, okToChngToIN is true if original pTerm satisfies
     ** case 1.  In that case, construct a new virtual term that is 
     ** pTerm converted into an IN operator.
-    **
-    ** EV: R-00211-15100
     */
     if( okToChngToIN ){
       Expr *pDup;            /* A transient duplicate expression */
@@ -105603,7 +106301,7 @@ static void exprAnalyzeOrTerm(
         assert( pOrTerm->leftCursor==iCursor );
         assert( pOrTerm->u.leftColumn==iColumn );
         pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0);
-        pList = sqlite3ExprListAppend(pWC->pParse, pList, pDup);
+        pList = sqlite3ExprListAppend(pWInfo->pParse, pList, pDup);
         pLeft = pOrTerm->pExpr->pLeft;
       }
       assert( pLeft!=0 );
@@ -105652,6 +106350,7 @@ static void exprAnalyze(
   WhereClause *pWC,         /* the WHERE clause */
   int idxTerm               /* Index of the term to be analyzed */
 ){
+  WhereInfo *pWInfo = pWC->pWInfo; /* WHERE clause processing context */
   WhereTerm *pTerm;                /* The term to be analyzed */
   WhereMaskSet *pMaskSet;          /* Set of table index masks */
   Expr *pExpr;                     /* The expression to be analyzed */
@@ -105662,14 +106361,14 @@ static void exprAnalyze(
   int isComplete = 0;              /* RHS of LIKE/GLOB ends with wildcard */
   int noCase = 0;                  /* LIKE/GLOB distinguishes case */
   int op;                          /* Top-level operator.  pExpr->op */
-  Parse *pParse = pWC->pParse;     /* Parsing context */
+  Parse *pParse = pWInfo->pParse;  /* Parsing context */
   sqlite3 *db = pParse->db;        /* Database connection */
 
   if( db->mallocFailed ){
     return;
   }
   pTerm = &pWC->a[idxTerm];
-  pMaskSet = pWC->pMaskSet;
+  pMaskSet = &pWInfo->sMaskSet;
   pExpr = pTerm->pExpr;
   assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE );
   prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
@@ -105774,6 +106473,7 @@ static void exprAnalyze(
       pNewExpr = sqlite3PExpr(pParse, ops[i], 
                              sqlite3ExprDup(db, pExpr->pLeft, 0),
                              sqlite3ExprDup(db, pList->a[i].pExpr, 0), 0);
+      transferJoinMarkings(pNewExpr, pExpr);
       idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
       testcase( idxNew==0 );
       exprAnalyze(pSrc, pWC, idxNew);
@@ -105830,9 +106530,7 @@ static void exprAnalyze(
         ** inequality.  To avoid this, make sure to also run the full
         ** LIKE on all candidate expressions by clearing the isComplete flag
         */
-        if( c=='A'-1 ) isComplete = 0;   /* EV: R-64339-08207 */
-
-
+        if( c=='A'-1 ) isComplete = 0;
         c = sqlite3UpperToLower[c];
       }
       *pC = c + 1;
@@ -105843,6 +106541,7 @@ static void exprAnalyze(
     pNewExpr1 = sqlite3PExpr(pParse, TK_GE, 
            sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName),
            pStr1, 0);
+    transferJoinMarkings(pNewExpr1, pExpr);
     idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
     testcase( idxNew1==0 );
     exprAnalyze(pSrc, pWC, idxNew1);
@@ -105850,6 +106549,7 @@ static void exprAnalyze(
     pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
            sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName),
            pStr2, 0);
+    transferJoinMarkings(pNewExpr2, pExpr);
     idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
     testcase( idxNew2==0 );
     exprAnalyze(pSrc, pWC, idxNew2);
@@ -105913,6 +106613,7 @@ static void exprAnalyze(
   if( pExpr->op==TK_NOTNULL
    && pExpr->pLeft->op==TK_COLUMN
    && pExpr->pLeft->iColumn>=0
+   && OptimizationEnabled(db, SQLITE_Stat3)
   ){
     Expr *pNewExpr;
     Expr *pLeft = pExpr->pLeft;
@@ -105947,11 +106648,8 @@ static void exprAnalyze(
 }
 
 /*
-** This function searches the expression list passed as the second argument
-** for an expression of type TK_COLUMN that refers to the same column and
-** uses the same collation sequence as the iCol'th column of index pIdx.
-** Argument iBase is the cursor number used for the table that pIdx refers
-** to.
+** This function searches pList for a entry that matches the iCol-th column
+** of index pIdx.
 **
 ** If such an expression is found, its index in pList->a[] is returned. If
 ** no expression is found, -1 is returned.
@@ -105983,76 +106681,17 @@ static int findIndexCol(
 }
 
 /*
-** This routine determines if pIdx can be used to assist in processing a
-** DISTINCT qualifier. In other words, it tests whether or not using this
-** index for the outer loop guarantees that rows with equal values for
-** all expressions in the pDistinct list are delivered grouped together.
-**
-** For example, the query 
-**
-**   SELECT DISTINCT a, b, c FROM tbl WHERE a = ?
-**
-** can benefit from any index on columns "b" and "c".
-*/
-static int isDistinctIndex(
-  Parse *pParse,                  /* Parsing context */
-  WhereClause *pWC,               /* The WHERE clause */
-  Index *pIdx,                    /* The index being considered */
-  int base,                       /* Cursor number for the table pIdx is on */
-  ExprList *pDistinct,            /* The DISTINCT expressions */
-  int nEqCol                      /* Number of index columns with == */
-){
-  Bitmask mask = 0;               /* Mask of unaccounted for pDistinct exprs */
-  int i;                          /* Iterator variable */
-
-  assert( pDistinct!=0 );
-  if( pIdx->zName==0 || pDistinct->nExpr>=BMS ) return 0;
-  testcase( pDistinct->nExpr==BMS-1 );
-
-  /* Loop through all the expressions in the distinct list. If any of them
-  ** are not simple column references, return early. Otherwise, test if the
-  ** WHERE clause contains a "col=X" clause. If it does, the expression
-  ** can be ignored. If it does not, and the column does not belong to the
-  ** same table as index pIdx, return early. Finally, if there is no
-  ** matching "col=X" expression and the column is on the same table as pIdx,
-  ** set the corresponding bit in variable mask.
-  */
-  for(i=0; i<pDistinct->nExpr; i++){
-    WhereTerm *pTerm;
-    Expr *p = sqlite3ExprSkipCollate(pDistinct->a[i].pExpr);
-    if( p->op!=TK_COLUMN ) return 0;
-    pTerm = findTerm(pWC, p->iTable, p->iColumn, ~(Bitmask)0, WO_EQ, 0);
-    if( pTerm ){
-      Expr *pX = pTerm->pExpr;
-      CollSeq *p1 = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
-      CollSeq *p2 = sqlite3ExprCollSeq(pParse, p);
-      if( p1==p2 ) continue;
-    }
-    if( p->iTable!=base ) return 0;
-    mask |= (((Bitmask)1) << i);
-  }
-
-  for(i=nEqCol; mask && i<pIdx->nColumn; i++){
-    int iExpr = findIndexCol(pParse, pDistinct, base, pIdx, i);
-    if( iExpr<0 ) break;
-    mask &= ~(((Bitmask)1) << iExpr);
-  }
-
-  return (mask==0);
-}
-
-
-/*
 ** Return true if the DISTINCT expression-list passed as the third argument
-** is redundant. A DISTINCT list is redundant if the database contains a
-** UNIQUE index that guarantees that the result of the query will be distinct
-** anyway.
+** is redundant.
+**
+** A DISTINCT list is redundant if the database contains some subset of
+** columns that are unique and non-null.
 */
 static int isDistinctRedundant(
-  Parse *pParse,
-  SrcList *pTabList,
-  WhereClause *pWC,
-  ExprList *pDistinct
+  Parse *pParse,            /* Parsing context */
+  SrcList *pTabList,        /* The FROM clause */
+  WhereClause *pWC,         /* The WHERE clause */
+  ExprList *pDistinct       /* The result set that needs to be DISTINCT */
 ){
   Table *pTab;
   Index *pIdx;
@@ -106108,21 +106747,76 @@ static int isDistinctRedundant(
   return 0;
 }
 
+/* 
+** Find (an approximate) sum of two WhereCosts.  This computation is
+** not a simple "+" operator because WhereCost is stored as a logarithmic
+** value.
+** 
+*/
+static WhereCost whereCostAdd(WhereCost a, WhereCost b){
+  static const unsigned char x[] = {
+     10, 10,                         /* 0,1 */
+      9, 9,                          /* 2,3 */
+      8, 8,                          /* 4,5 */
+      7, 7, 7,                       /* 6,7,8 */
+      6, 6, 6,                       /* 9,10,11 */
+      5, 5, 5,                       /* 12-14 */
+      4, 4, 4, 4,                    /* 15-18 */
+      3, 3, 3, 3, 3, 3,              /* 19-24 */
+      2, 2, 2, 2, 2, 2, 2,           /* 25-31 */
+  };
+  if( a>=b ){
+    if( a>b+49 ) return a;
+    if( a>b+31 ) return a+1;
+    return a+x[a-b];
+  }else{
+    if( b>a+49 ) return b;
+    if( b>a+31 ) return b+1;
+    return b+x[b-a];
+  }
+}
+
 /*
-** Prepare a crude estimate of the logarithm of the input value.
-** The results need not be exact.  This is only used for estimating
-** the total cost of performing operations with O(logN) or O(NlogN)
-** complexity.  Because N is just a guess, it is no great tragedy if
-** logN is a little off.
+** Convert an integer into a WhereCost.  In other words, compute a
+** good approximatation for 10*log2(x).
 */
-static double estLog(double N){
-  double logN = 1;
-  double x = 10;
-  while( N>x ){
-    logN += 1;
-    x *= 10;
+static WhereCost whereCost(tRowcnt x){
+  static WhereCost a[] = { 0, 2, 3, 5, 6, 7, 8, 9 };
+  WhereCost y = 40;
+  if( x<8 ){
+    if( x<2 ) return 0;
+    while( x<8 ){  y -= 10; x <<= 1; }
+  }else{
+    while( x>255 ){ y += 40; x >>= 4; }
+    while( x>15 ){  y += 10; x >>= 1; }
   }
-  return logN;
+  return a[x&7] + y - 10;
+}
+
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+/*
+** Convert a double (as received from xBestIndex of a virtual table)
+** into a WhereCost.  In other words, compute an approximation for
+** 10*log2(x).
+*/
+static WhereCost whereCostFromDouble(double x){
+  u64 a;
+  WhereCost e;
+  assert( sizeof(x)==8 && sizeof(a)==8 );
+  if( x<=1 ) return 0;
+  if( x<=2000000000 ) return whereCost((tRowcnt)x);
+  memcpy(&a, &x, 8);
+  e = (a>>52) - 1022;
+  return e*10;
+}
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
+
+/*
+** Estimate the logarithm of the input value to base 2.
+*/
+static WhereCost estLog(WhereCost N){
+  WhereCost x = whereCost(N);
+  return x>33 ? x - 33 : 0;
 }
 
 /*
@@ -106131,7 +106825,7 @@ static double estLog(double N){
 ** SQLITE_TEST or SQLITE_DEBUG are defined, then these routines
 ** are no-ops.
 */
-#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_DEBUG)
+#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(WHERETRACE_ENABLED)
 static void TRACE_IDX_INPUTS(sqlite3_index_info *p){
   int i;
   if( !sqlite3WhereTrace ) return;
@@ -106169,107 +106863,6 @@ static void TRACE_IDX_OUTPUTS(sqlite3_index_info *p){
 #define TRACE_IDX_OUTPUTS(A)
 #endif
 
-/* 
-** Required because bestIndex() is called by bestOrClauseIndex() 
-*/
-static void bestIndex(WhereBestIdx*);
-
-/*
-** This routine attempts to find an scanning strategy that can be used 
-** to optimize an 'OR' expression that is part of a WHERE clause. 
-**
-** The table associated with FROM clause term pSrc may be either a
-** regular B-Tree table or a virtual table.
-*/
-static void bestOrClauseIndex(WhereBestIdx *p){
-#ifndef SQLITE_OMIT_OR_OPTIMIZATION
-  WhereClause *pWC = p->pWC;           /* The WHERE clause */
-  struct SrcList_item *pSrc = p->pSrc; /* The FROM clause term to search */
-  const int iCur = pSrc->iCursor;      /* The cursor of the table  */
-  const Bitmask maskSrc = getMask(pWC->pMaskSet, iCur);  /* Bitmask for pSrc */
-  WhereTerm * const pWCEnd = &pWC->a[pWC->nTerm];        /* End of pWC->a[] */
-  WhereTerm *pTerm;                    /* A single term of the WHERE clause */
-
-  /* The OR-clause optimization is disallowed if the INDEXED BY or
-  ** NOT INDEXED clauses are used or if the WHERE_AND_ONLY bit is set. */
-  if( pSrc->notIndexed || pSrc->pIndex!=0 ){
-    return;
-  }
-  if( pWC->wctrlFlags & WHERE_AND_ONLY ){
-    return;
-  }
-
-  /* Search the WHERE clause terms for a usable WO_OR term. */
-  for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
-    if( (pTerm->eOperator & WO_OR)!=0
-     && ((pTerm->prereqAll & ~maskSrc) & p->notReady)==0
-     && (pTerm->u.pOrInfo->indexable & maskSrc)!=0 
-    ){
-      WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc;
-      WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm];
-      WhereTerm *pOrTerm;
-      int flags = WHERE_MULTI_OR;
-      double rTotal = 0;
-      double nRow = 0;
-      Bitmask used = 0;
-      WhereBestIdx sBOI;
-
-      sBOI = *p;
-      sBOI.pOrderBy = 0;
-      sBOI.pDistinct = 0;
-      sBOI.ppIdxInfo = 0;
-      for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
-        WHERETRACE(("... Multi-index OR testing for term %d of %d....\n", 
-          (pOrTerm - pOrWC->a), (pTerm - pWC->a)
-        ));
-        if( (pOrTerm->eOperator& WO_AND)!=0 ){
-          sBOI.pWC = &pOrTerm->u.pAndInfo->wc;
-          bestIndex(&sBOI);
-        }else if( pOrTerm->leftCursor==iCur ){
-          WhereClause tempWC;
-          tempWC.pParse = pWC->pParse;
-          tempWC.pMaskSet = pWC->pMaskSet;
-          tempWC.pOuter = pWC;
-          tempWC.op = TK_AND;
-          tempWC.a = pOrTerm;
-          tempWC.wctrlFlags = 0;
-          tempWC.nTerm = 1;
-          sBOI.pWC = &tempWC;
-          bestIndex(&sBOI);
-        }else{
-          continue;
-        }
-        rTotal += sBOI.cost.rCost;
-        nRow += sBOI.cost.plan.nRow;
-        used |= sBOI.cost.used;
-        if( rTotal>=p->cost.rCost ) break;
-      }
-
-      /* If there is an ORDER BY clause, increase the scan cost to account 
-      ** for the cost of the sort. */
-      if( p->pOrderBy!=0 ){
-        WHERETRACE(("... sorting increases OR cost %.9g to %.9g\n",
-                    rTotal, rTotal+nRow*estLog(nRow)));
-        rTotal += nRow*estLog(nRow);
-      }
-
-      /* If the cost of scanning using this OR term for optimization is
-      ** less than the current cost stored in pCost, replace the contents
-      ** of pCost. */
-      WHERETRACE(("... multi-index OR cost=%.9g nrow=%.9g\n", rTotal, nRow));
-      if( rTotal<p->cost.rCost ){
-        p->cost.rCost = rTotal;
-        p->cost.used = used;
-        p->cost.plan.nRow = nRow;
-        p->cost.plan.nOBSat = p->i ? p->aLevel[p->i-1].plan.nOBSat : 0;
-        p->cost.plan.wsFlags = flags;
-        p->cost.plan.u.pTerm = pTerm;
-      }
-    }
-  }
-#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
-}
-
 #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
 /*
 ** Return TRUE if the WHERE clause term pTerm is of a form where it
@@ -106285,88 +106878,13 @@ static int termCanDriveIndex(
   if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
   if( (pTerm->eOperator & WO_EQ)==0 ) return 0;
   if( (pTerm->prereqRight & notReady)!=0 ) return 0;
+  if( pTerm->u.leftColumn<0 ) return 0;
   aff = pSrc->pTab->aCol[pTerm->u.leftColumn].affinity;
   if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0;
   return 1;
 }
 #endif
 
-#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
-/*
-** If the query plan for pSrc specified in pCost is a full table scan
-** and indexing is allows (if there is no NOT INDEXED clause) and it
-** possible to construct a transient index that would perform better
-** than a full table scan even when the cost of constructing the index
-** is taken into account, then alter the query plan to use the
-** transient index.
-*/
-static void bestAutomaticIndex(WhereBestIdx *p){
-  Parse *pParse = p->pParse;            /* The parsing context */
-  WhereClause *pWC = p->pWC;            /* The WHERE clause */
-  struct SrcList_item *pSrc = p->pSrc;  /* The FROM clause term to search */
-  double nTableRow;                     /* Rows in the input table */
-  double logN;                          /* log(nTableRow) */
-  double costTempIdx;         /* per-query cost of the transient index */
-  WhereTerm *pTerm;           /* A single term of the WHERE clause */
-  WhereTerm *pWCEnd;          /* End of pWC->a[] */
-  Table *pTable;              /* Table tht might be indexed */
-
-  if( pParse->nQueryLoop<=(double)1 ){
-    /* There is no point in building an automatic index for a single scan */
-    return;
-  }
-  if( (pParse->db->flags & SQLITE_AutoIndex)==0 ){
-    /* Automatic indices are disabled at run-time */
-    return;
-  }
-  if( (p->cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0
-   && (p->cost.plan.wsFlags & WHERE_COVER_SCAN)==0
-  ){
-    /* We already have some kind of index in use for this query. */
-    return;
-  }
-  if( pSrc->viaCoroutine ){
-    /* Cannot index a co-routine */
-    return;
-  }
-  if( pSrc->notIndexed ){
-    /* The NOT INDEXED clause appears in the SQL. */
-    return;
-  }
-  if( pSrc->isCorrelated ){
-    /* The source is a correlated sub-query. No point in indexing it. */
-    return;
-  }
-
-  assert( pParse->nQueryLoop >= (double)1 );
-  pTable = pSrc->pTab;
-  nTableRow = pTable->nRowEst;
-  logN = estLog(nTableRow);
-  costTempIdx = 2*logN*(nTableRow/pParse->nQueryLoop + 1);
-  if( costTempIdx>=p->cost.rCost ){
-    /* The cost of creating the transient table would be greater than
-    ** doing the full table scan */
-    return;
-  }
-
-  /* Search for any equality comparison term */
-  pWCEnd = &pWC->a[pWC->nTerm];
-  for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
-    if( termCanDriveIndex(pTerm, pSrc, p->notReady) ){
-      WHERETRACE(("auto-index reduces cost from %.1f to %.1f\n",
-                    p->cost.rCost, costTempIdx));
-      p->cost.rCost = costTempIdx;
-      p->cost.plan.nRow = logN + 1;
-      p->cost.plan.wsFlags = WHERE_TEMP_INDEX;
-      p->cost.used = pTerm->prereqRight;
-      break;
-    }
-  }
-}
-#else
-# define bestAutomaticIndex(A)  /* no-op */
-#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */
-
 
 #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
 /*
@@ -106396,8 +106914,10 @@ static void constructAutomaticIndex(
   int i;                      /* Loop counter */
   int mxBitCol;               /* Maximum column in pSrc->colUsed */
   CollSeq *pColl;             /* Collating sequence to on a column */
+  WhereLoop *pLoop;           /* The Loop object */
   Bitmask idxCols;            /* Bitmap of columns used for indexing */
   Bitmask extraCols;          /* Bitmap of additional columns */
+  u8 sentWarning = 0;         /* True if a warnning has been issued */
 
   /* Generate code to skip over the creation and initialization of the
   ** transient index on 2nd and subsequent iterations of the loop. */
@@ -106410,21 +106930,31 @@ static void constructAutomaticIndex(
   nColumn = 0;
   pTable = pSrc->pTab;
   pWCEnd = &pWC->a[pWC->nTerm];
+  pLoop = pLevel->pWLoop;
   idxCols = 0;
   for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
     if( termCanDriveIndex(pTerm, pSrc, notReady) ){
       int iCol = pTerm->u.leftColumn;
-      Bitmask cMask = iCol>=BMS ? ((Bitmask)1)<<(BMS-1) : ((Bitmask)1)<<iCol;
+      Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
       testcase( iCol==BMS );
       testcase( iCol==BMS-1 );
+      if( !sentWarning ){
+        sqlite3_log(SQLITE_WARNING_AUTOINDEX,
+            "automatic index on %s(%s)", pTable->zName,
+            pTable->aCol[iCol].zName);
+        sentWarning = 1;
+      }
       if( (idxCols & cMask)==0 ){
-        nColumn++;
+        if( whereLoopResize(pParse->db, pLoop, nColumn+1) ) return;
+        pLoop->aLTerm[nColumn++] = pTerm;
         idxCols |= cMask;
       }
     }
   }
   assert( nColumn>0 );
-  pLevel->plan.nEq = nColumn;
+  pLoop->u.btree.nEq = pLoop->nLTerm = nColumn;
+  pLoop->wsFlags = WHERE_COLUMN_EQ | WHERE_IDX_ONLY | WHERE_INDEXED
+                     | WHERE_AUTO_INDEX;
 
   /* Count the number of additional columns needed to create a
   ** covering index.  A "covering index" is an index that contains all
@@ -106434,17 +106964,17 @@ static void constructAutomaticIndex(
   ** original table changes and the index and table cannot both be used
   ** if they go out of sync.
   */
-  extraCols = pSrc->colUsed & (~idxCols | (((Bitmask)1)<<(BMS-1)));
+  extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1));
   mxBitCol = (pTable->nCol >= BMS-1) ? BMS-1 : pTable->nCol;
   testcase( pTable->nCol==BMS-1 );
   testcase( pTable->nCol==BMS-2 );
   for(i=0; i<mxBitCol; i++){
-    if( extraCols & (((Bitmask)1)<<i) ) nColumn++;
+    if( extraCols & MASKBIT(i) ) nColumn++;
   }
-  if( pSrc->colUsed & (((Bitmask)1)<<(BMS-1)) ){
+  if( pSrc->colUsed & MASKBIT(BMS-1) ){
     nColumn += pTable->nCol - BMS + 1;
   }
-  pLevel->plan.wsFlags |= WHERE_COLUMN_EQ | WHERE_IDX_ONLY | WO_EQ;
+  pLoop->wsFlags |= WHERE_COLUMN_EQ | WHERE_IDX_ONLY;
 
   /* Construct the Index object to describe this index */
   nByte = sizeof(Index);
@@ -106453,7 +106983,7 @@ static void constructAutomaticIndex(
   nByte += nColumn;                 /* Index.aSortOrder */
   pIdx = sqlite3DbMallocZero(pParse->db, nByte);
   if( pIdx==0 ) return;
-  pLevel->plan.u.pIdx = pIdx;
+  pLoop->u.btree.pIndex = pIdx;
   pIdx->azColl = (char**)&pIdx[1];
   pIdx->aiColumn = (int*)&pIdx->azColl[nColumn];
   pIdx->aSortOrder = (u8*)&pIdx->aiColumn[nColumn];
@@ -106465,7 +106995,9 @@ static void constructAutomaticIndex(
   for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
     if( termCanDriveIndex(pTerm, pSrc, notReady) ){
       int iCol = pTerm->u.leftColumn;
-      Bitmask cMask = iCol>=BMS ? ((Bitmask)1)<<(BMS-1) : ((Bitmask)1)<<iCol;
+      Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
+      testcase( iCol==BMS-1 );
+      testcase( iCol==BMS );
       if( (idxCols & cMask)==0 ){
         Expr *pX = pTerm->pExpr;
         idxCols |= cMask;
@@ -106476,18 +107008,18 @@ static void constructAutomaticIndex(
       }
     }
   }
-  assert( (u32)n==pLevel->plan.nEq );
+  assert( (u32)n==pLoop->u.btree.nEq );
 
   /* Add additional columns needed to make the automatic index into
   ** a covering index */
   for(i=0; i<mxBitCol; i++){
-    if( extraCols & (((Bitmask)1)<<i) ){
+    if( extraCols & MASKBIT(i) ){
       pIdx->aiColumn[n] = i;
       pIdx->azColl[n] = "BINARY";
       n++;
     }
   }
-  if( pSrc->colUsed & (((Bitmask)1)<<(BMS-1)) ){
+  if( pSrc->colUsed & MASKBIT(BMS-1) ){
     for(i=BMS-1; i<pTable->nCol; i++){
       pIdx->aiColumn[n] = i;
       pIdx->azColl[n] = "BINARY";
@@ -106499,6 +107031,7 @@ static void constructAutomaticIndex(
   /* Create the automatic index */
   pKeyinfo = sqlite3IndexKeyinfo(pParse, pIdx);
   assert( pLevel->iIdxCur>=0 );
+  pLevel->iIdxCur = pParse->nTab++;
   sqlite3VdbeAddOp4(v, OP_OpenAutoindex, pLevel->iIdxCur, nColumn+1, 0,
                     (char*)pKeyinfo, P4_KEYINFO_HANDOFF);
   VdbeComment((v, "for %s", pTable->zName));
@@ -106506,7 +107039,7 @@ static void constructAutomaticIndex(
   /* Fill the automatic index with content */
   addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur);
   regRecord = sqlite3GetTempReg(pParse);
-  sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 1);
+  sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 1, 0);
   sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
   sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
   sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1);
@@ -106525,11 +107058,12 @@ static void constructAutomaticIndex(
 ** responsibility of the caller to eventually release the structure
 ** by passing the pointer returned by this function to sqlite3_free().
 */
-static sqlite3_index_info *allocateIndexInfo(WhereBestIdx *p){
-  Parse *pParse = p->pParse; 
-  WhereClause *pWC = p->pWC;
-  struct SrcList_item *pSrc = p->pSrc;
-  ExprList *pOrderBy = p->pOrderBy;
+static sqlite3_index_info *allocateIndexInfo(
+  Parse *pParse,
+  WhereClause *pWC,
+  struct SrcList_item *pSrc,
+  ExprList *pOrderBy
+){
   int i, j;
   int nTerm;
   struct sqlite3_index_constraint *pIdxCons;
@@ -106539,8 +107073,6 @@ static sqlite3_index_info *allocateIndexInfo(WhereBestIdx *p){
   int nOrderBy;
   sqlite3_index_info *pIdxInfo;
 
-  WHERETRACE(("Recomputing index info for %s...\n", pSrc->pTab->zName));
-
   /* Count the number of possible WHERE clause constraints referring
   ** to this virtual table */
   for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
@@ -106576,7 +107108,6 @@ static sqlite3_index_info *allocateIndexInfo(WhereBestIdx *p){
                            + sizeof(*pIdxOrderBy)*nOrderBy );
   if( pIdxInfo==0 ){
     sqlite3ErrorMsg(pParse, "out of memory");
-    /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
     return 0;
   }
 
@@ -106632,8 +107163,8 @@ static sqlite3_index_info *allocateIndexInfo(WhereBestIdx *p){
 /*
 ** The table object reference passed as the second argument to this function
 ** must represent a virtual table. This function invokes the xBestIndex()
-** method of the virtual table with the sqlite3_index_info pointer passed
-** as the argument.
+** method of the virtual table with the sqlite3_index_info object that
+** comes in as the 3rd argument to this function.
 **
 ** If an error occurs, pParse is populated with an error message and a
 ** non-zero value is returned. Otherwise, 0 is returned and the output
@@ -106648,7 +107179,6 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
   int i;
   int rc;
 
-  WHERETRACE(("xBestIndex for %s\n", pTab->zName));
   TRACE_IDX_INPUTS(p);
   rc = pVtab->pModule->xBestIndex(pVtab, p);
   TRACE_IDX_OUTPUTS(p);
@@ -106674,208 +107204,9 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
 
   return pParse->nErr;
 }
+#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */
 
 
-/*
-** Compute the best index for a virtual table.
-**
-** The best index is computed by the xBestIndex method of the virtual
-** table module.  This routine is really just a wrapper that sets up
-** the sqlite3_index_info structure that is used to communicate with
-** xBestIndex.
-**
-** In a join, this routine might be called multiple times for the
-** same virtual table.  The sqlite3_index_info structure is created
-** and initialized on the first invocation and reused on all subsequent
-** invocations.  The sqlite3_index_info structure is also used when
-** code is generated to access the virtual table.  The whereInfoDelete() 
-** routine takes care of freeing the sqlite3_index_info structure after
-** everybody has finished with it.
-*/
-static void bestVirtualIndex(WhereBestIdx *p){
-  Parse *pParse = p->pParse;      /* The parsing context */
-  WhereClause *pWC = p->pWC;      /* The WHERE clause */
-  struct SrcList_item *pSrc = p->pSrc; /* The FROM clause term to search */
-  Table *pTab = pSrc->pTab;
-  sqlite3_index_info *pIdxInfo;
-  struct sqlite3_index_constraint *pIdxCons;
-  struct sqlite3_index_constraint_usage *pUsage;
-  WhereTerm *pTerm;
-  int i, j;
-  int nOrderBy;
-  int bAllowIN;                   /* Allow IN optimizations */
-  double rCost;
-
-  /* Make sure wsFlags is initialized to some sane value. Otherwise, if the 
-  ** malloc in allocateIndexInfo() fails and this function returns leaving
-  ** wsFlags in an uninitialized state, the caller may behave unpredictably.
-  */
-  memset(&p->cost, 0, sizeof(p->cost));
-  p->cost.plan.wsFlags = WHERE_VIRTUALTABLE;
-
-  /* If the sqlite3_index_info structure has not been previously
-  ** allocated and initialized, then allocate and initialize it now.
-  */
-  pIdxInfo = *p->ppIdxInfo;
-  if( pIdxInfo==0 ){
-    *p->ppIdxInfo = pIdxInfo = allocateIndexInfo(p);
-  }
-  if( pIdxInfo==0 ){
-    return;
-  }
-
-  /* At this point, the sqlite3_index_info structure that pIdxInfo points
-  ** to will have been initialized, either during the current invocation or
-  ** during some prior invocation.  Now we just have to customize the
-  ** details of pIdxInfo for the current invocation and pass it to
-  ** xBestIndex.
-  */
-
-  /* The module name must be defined. Also, by this point there must
-  ** be a pointer to an sqlite3_vtab structure. Otherwise
-  ** sqlite3ViewGetColumnNames() would have picked up the error. 
-  */
-  assert( pTab->azModuleArg && pTab->azModuleArg[0] );
-  assert( sqlite3GetVTable(pParse->db, pTab) );
-
-  /* Try once or twice.  On the first attempt, allow IN optimizations.
-  ** If an IN optimization is accepted by the virtual table xBestIndex
-  ** method, but the  pInfo->aConstrainUsage.omit flag is not set, then
-  ** the query will not work because it might allow duplicate rows in
-  ** output.  In that case, run the xBestIndex method a second time
-  ** without the IN constraints.  Usually this loop only runs once.
-  ** The loop will exit using a "break" statement.
-  */
-  for(bAllowIN=1; 1; bAllowIN--){
-    assert( bAllowIN==0 || bAllowIN==1 );
-
-    /* Set the aConstraint[].usable fields and initialize all 
-    ** output variables to zero.
-    **
-    ** aConstraint[].usable is true for constraints where the right-hand
-    ** side contains only references to tables to the left of the current
-    ** table.  In other words, if the constraint is of the form:
-    **
-    **           column = expr
-    **
-    ** and we are evaluating a join, then the constraint on column is 
-    ** only valid if all tables referenced in expr occur to the left
-    ** of the table containing column.
-    **
-    ** The aConstraints[] array contains entries for all constraints
-    ** on the current table.  That way we only have to compute it once
-    ** even though we might try to pick the best index multiple times.
-    ** For each attempt at picking an index, the order of tables in the
-    ** join might be different so we have to recompute the usable flag
-    ** each time.
-    */
-    pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
-    pUsage = pIdxInfo->aConstraintUsage;
-    for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
-      j = pIdxCons->iTermOffset;
-      pTerm = &pWC->a[j];
-      if( (pTerm->prereqRight&p->notReady)==0
-       && (bAllowIN || (pTerm->eOperator & WO_IN)==0)
-      ){
-        pIdxCons->usable = 1;
-      }else{
-        pIdxCons->usable = 0;
-      }
-    }
-    memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
-    if( pIdxInfo->needToFreeIdxStr ){
-      sqlite3_free(pIdxInfo->idxStr);
-    }
-    pIdxInfo->idxStr = 0;
-    pIdxInfo->idxNum = 0;
-    pIdxInfo->needToFreeIdxStr = 0;
-    pIdxInfo->orderByConsumed = 0;
-    /* ((double)2) In case of SQLITE_OMIT_FLOATING_POINT... */
-    pIdxInfo->estimatedCost = SQLITE_BIG_DBL / ((double)2);
-    nOrderBy = pIdxInfo->nOrderBy;
-    if( !p->pOrderBy ){
-      pIdxInfo->nOrderBy = 0;
-    }
-  
-    if( vtabBestIndex(pParse, pTab, pIdxInfo) ){
-      return;
-    }
-  
-    pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
-    for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
-      if( pUsage[i].argvIndex>0 ){
-        j = pIdxCons->iTermOffset;
-        pTerm = &pWC->a[j];
-        p->cost.used |= pTerm->prereqRight;
-        if( (pTerm->eOperator & WO_IN)!=0 ){
-          if( pUsage[i].omit==0 ){
-            /* Do not attempt to use an IN constraint if the virtual table
-            ** says that the equivalent EQ constraint cannot be safely omitted.
-            ** If we do attempt to use such a constraint, some rows might be
-            ** repeated in the output. */
-            break;
-          }
-          /* A virtual table that is constrained by an IN clause may not
-          ** consume the ORDER BY clause because (1) the order of IN terms
-          ** is not necessarily related to the order of output terms and
-          ** (2) Multiple outputs from a single IN value will not merge
-          ** together.  */
-          pIdxInfo->orderByConsumed = 0;
-        }
-      }
-    }
-    if( i>=pIdxInfo->nConstraint ) break;
-  }
-
-  /* The orderByConsumed signal is only valid if all outer loops collectively
-  ** generate just a single row of output.
-  */
-  if( pIdxInfo->orderByConsumed ){
-    for(i=0; i<p->i; i++){
-      if( (p->aLevel[i].plan.wsFlags & WHERE_UNIQUE)==0 ){
-        pIdxInfo->orderByConsumed = 0;
-      }
-    }
-  }
-  
-  /* If there is an ORDER BY clause, and the selected virtual table index
-  ** does not satisfy it, increase the cost of the scan accordingly. This
-  ** matches the processing for non-virtual tables in bestBtreeIndex().
-  */
-  rCost = pIdxInfo->estimatedCost;
-  if( p->pOrderBy && pIdxInfo->orderByConsumed==0 ){
-    rCost += estLog(rCost)*rCost;
-  }
-
-  /* The cost is not allowed to be larger than SQLITE_BIG_DBL (the
-  ** inital value of lowestCost in this loop. If it is, then the
-  ** (cost<lowestCost) test below will never be true.
-  ** 
-  ** Use "(double)2" instead of "2.0" in case OMIT_FLOATING_POINT 
-  ** is defined.
-  */
-  if( (SQLITE_BIG_DBL/((double)2))<rCost ){
-    p->cost.rCost = (SQLITE_BIG_DBL/((double)2));
-  }else{
-    p->cost.rCost = rCost;
-  }
-  p->cost.plan.u.pVtabIdx = pIdxInfo;
-  if( pIdxInfo->orderByConsumed ){
-    p->cost.plan.wsFlags |= WHERE_ORDERED;
-    p->cost.plan.nOBSat = nOrderBy;
-  }else{
-    p->cost.plan.nOBSat = p->i ? p->aLevel[p->i-1].plan.nOBSat : 0;
-  }
-  p->cost.plan.nEq = 0;
-  pIdxInfo->nOrderBy = nOrderBy;
-
-  /* Try to find a more efficient access pattern by using multiple indexes
-  ** to optimize an OR expression within the WHERE clause. 
-  */
-  bestOrClauseIndex(p);
-}
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
 #ifdef SQLITE_ENABLE_STAT3
 /*
 ** Estimate the location of a particular key among all keys in an
@@ -106961,9 +107292,10 @@ static int whereKeyStats(
         assert( pColl->enc==SQLITE_UTF8 );
       }else{
         pColl = sqlite3GetCollSeq(pParse, SQLITE_UTF8, 0, *pIdx->azColl);
-        if( pColl==0 ){
-          return SQLITE_ERROR;
-        }
+        /* If the collating sequence was unavailable, we should have failed
+        ** long ago and never reached this point.  But we'll check just to
+        ** be doubly sure. */
+        if( NEVER(pColl==0) ) return SQLITE_ERROR;
         z = (const u8 *)sqlite3ValueText(pVal, pColl->enc);
         if( !z ){
           return SQLITE_NOMEM;
@@ -107064,7 +107396,7 @@ static int valueFromExpr(
   ){
     int iVar = pExpr->iColumn;
     sqlite3VdbeSetVarmask(pParse->pVdbe, iVar);
-    *pp = sqlite3VdbeGetValue(pParse->pReprepare, iVar, aff);
+    *pp = sqlite3VdbeGetBoundValue(pParse->pReprepare, iVar, aff);
     return SQLITE_OK;
   }
   return sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, aff, pp);
@@ -107116,13 +107448,13 @@ static int whereRangeScanEst(
   int nEq,             /* index into p->aCol[] of the range-compared column */
   WhereTerm *pLower,   /* Lower bound on the range. ex: "x>123" Might be NULL */
   WhereTerm *pUpper,   /* Upper bound on the range. ex: "x<455" Might be NULL */
-  double *pRangeDiv   /* OUT: Reduce search space by this divisor */
+  WhereCost *pRangeDiv /* OUT: Reduce search space by this divisor */
 ){
   int rc = SQLITE_OK;
 
 #ifdef SQLITE_ENABLE_STAT3
 
-  if( nEq==0 && p->nSample ){
+  if( nEq==0 && p->nSample && OptimizationEnabled(pParse->db, SQLITE_Stat3) ){
     sqlite3_value *pRangeVal;
     tRowcnt iLower = 0;
     tRowcnt iUpper = p->aiRowEst[0];
@@ -107154,13 +107486,13 @@ static int whereRangeScanEst(
       sqlite3ValueFree(pRangeVal);
     }
     if( rc==SQLITE_OK ){
-      if( iUpper<=iLower ){
-        *pRangeDiv = (double)p->aiRowEst[0];
-      }else{
-        *pRangeDiv = (double)p->aiRowEst[0]/(double)(iUpper - iLower);
+      WhereCost iBase = whereCost(p->aiRowEst[0]);
+      if( iUpper>iLower ){
+        iBase -= whereCost(iUpper - iLower);
       }
-      WHERETRACE(("range scan regions: %u..%u  div=%g\n",
-                  (u32)iLower, (u32)iUpper, *pRangeDiv));
+      *pRangeDiv = iBase;
+      WHERETRACE(0x100, ("range scan regions: %u..%u  div=%d\n",
+                         (u32)iLower, (u32)iUpper, *pRangeDiv));
       return SQLITE_OK;
     }
   }
@@ -107170,9 +107502,15 @@ static int whereRangeScanEst(
   UNUSED_PARAMETER(nEq);
 #endif
   assert( pLower || pUpper );
-  *pRangeDiv = (double)1;
-  if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ) *pRangeDiv *= (double)4;
-  if( pUpper ) *pRangeDiv *= (double)4;
+  *pRangeDiv = 0;
+  /* TUNING:  Each inequality constraint reduces the search space 4-fold.
+  ** A BETWEEN operator, therefore, reduces the search space 16-fold */
+  if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ){
+    *pRangeDiv += 20;  assert( 20==whereCost(4) );
+  }
+  if( pUpper ){
+    *pRangeDiv += 20;  assert( 20==whereCost(4) );
+  }
   return rc;
 }
 
@@ -107198,7 +107536,7 @@ static int whereEqualScanEst(
   Parse *pParse,       /* Parsing & code generating context */
   Index *p,            /* The index whose left-most column is pTerm */
   Expr *pExpr,         /* Expression for VALUE in the x=VALUE constraint */
-  double *pnRow        /* Write the revised row estimate here */
+  tRowcnt *pnRow       /* Write the revised row estimate here */
 ){
   sqlite3_value *pRhs = 0;  /* VALUE on right-hand side of pTerm */
   u8 aff;                   /* Column affinity */
@@ -107217,7 +107555,7 @@ static int whereEqualScanEst(
   if( pRhs==0 ) return SQLITE_NOTFOUND;
   rc = whereKeyStats(pParse, p, pRhs, 0, a);
   if( rc==SQLITE_OK ){
-    WHERETRACE(("equality scan regions: %d\n", (int)a[1]));
+    WHERETRACE(0x100,("equality scan regions: %d\n", (int)a[1]));
     *pnRow = a[1];
   }
 whereEqualScanEst_cancel:
@@ -107247,12 +107585,12 @@ static int whereInScanEst(
   Parse *pParse,       /* Parsing & code generating context */
   Index *p,            /* The index whose left-most column is pTerm */
   ExprList *pList,     /* The value list on the RHS of "x IN (v1,v2,v3,...)" */
-  double *pnRow        /* Write the revised row estimate here */
+  tRowcnt *pnRow       /* Write the revised row estimate here */
 ){
-  int rc = SQLITE_OK;         /* Subfunction return code */
-  double nEst;                /* Number of rows for a single term */
-  double nRowEst = (double)0; /* New estimate of the number of rows */
-  int i;                      /* Loop counter */
+  int rc = SQLITE_OK;     /* Subfunction return code */
+  tRowcnt nEst;           /* Number of rows for a single term */
+  tRowcnt nRowEst = 0;    /* New estimate of the number of rows */
+  int i;                  /* Loop counter */
 
   assert( p->aSample!=0 );
   for(i=0; rc==SQLITE_OK && i<pList->nExpr; i++){
@@ -107263,886 +107601,13 @@ static int whereInScanEst(
   if( rc==SQLITE_OK ){
     if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0];
     *pnRow = nRowEst;
-    WHERETRACE(("IN row estimate: est=%g\n", nRowEst));
+    WHERETRACE(0x100,("IN row estimate: est=%g\n", nRowEst));
   }
   return rc;
 }
 #endif /* defined(SQLITE_ENABLE_STAT3) */
 
 /*
-** Check to see if column iCol of the table with cursor iTab will appear
-** in sorted order according to the current query plan.
-**
-** Return values:
-**
-**    0   iCol is not ordered
-**    1   iCol has only a single value
-**    2   iCol is in ASC order
-**    3   iCol is in DESC order
-*/
-static int isOrderedColumn(
-  WhereBestIdx *p,
-  int iTab,
-  int iCol
-){
-  int i, j;
-  WhereLevel *pLevel = &p->aLevel[p->i-1];
-  Index *pIdx;
-  u8 sortOrder;
-  for(i=p->i-1; i>=0; i--, pLevel--){
-    if( pLevel->iTabCur!=iTab ) continue;
-    if( (pLevel->plan.wsFlags & WHERE_ALL_UNIQUE)!=0 ){
-      return 1;
-    }
-    assert( (pLevel->plan.wsFlags & WHERE_ORDERED)!=0 );
-    if( (pIdx = pLevel->plan.u.pIdx)!=0 ){
-      if( iCol<0 ){
-        sortOrder = 0;
-        testcase( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 );
-      }else{
-        int n = pIdx->nColumn;
-        for(j=0; j<n; j++){
-          if( iCol==pIdx->aiColumn[j] ) break;
-        }
-        if( j>=n ) return 0;
-        sortOrder = pIdx->aSortOrder[j];
-        testcase( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 );
-      }
-    }else{
-      if( iCol!=(-1) ) return 0;
-      sortOrder = 0;
-      testcase( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 );
-    }
-    if( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 ){
-      assert( sortOrder==0 || sortOrder==1 );
-      testcase( sortOrder==1 );
-      sortOrder = 1 - sortOrder;
-    }
-    return sortOrder+2;
-  }
-  return 0;
-}
-
-/*
-** This routine decides if pIdx can be used to satisfy the ORDER BY
-** clause, either in whole or in part.  The return value is the 
-** cumulative number of terms in the ORDER BY clause that are satisfied
-** by the index pIdx and other indices in outer loops.
-**
-** The table being queried has a cursor number of "base".  pIdx is the
-** index that is postulated for use to access the table.
-**
-** The *pbRev value is set to 0 order 1 depending on whether or not
-** pIdx should be run in the forward order or in reverse order.
-*/
-static int isSortingIndex(
-  WhereBestIdx *p,    /* Best index search context */
-  Index *pIdx,        /* The index we are testing */
-  int base,           /* Cursor number for the table to be sorted */
-  int *pbRev,         /* Set to 1 for reverse-order scan of pIdx */
-  int *pbObUnique     /* ORDER BY column values will different in every row */
-){
-  int i;                        /* Number of pIdx terms used */
-  int j;                        /* Number of ORDER BY terms satisfied */
-  int sortOrder = 2;            /* 0: forward.  1: backward.  2: unknown */
-  int nTerm;                    /* Number of ORDER BY terms */
-  struct ExprList_item *pOBItem;/* A term of the ORDER BY clause */
-  Table *pTab = pIdx->pTable;   /* Table that owns index pIdx */
-  ExprList *pOrderBy;           /* The ORDER BY clause */
-  Parse *pParse = p->pParse;    /* Parser context */
-  sqlite3 *db = pParse->db;     /* Database connection */
-  int nPriorSat;                /* ORDER BY terms satisfied by outer loops */
-  int seenRowid = 0;            /* True if an ORDER BY rowid term is seen */
-  int uniqueNotNull;            /* pIdx is UNIQUE with all terms are NOT NULL */
-  int outerObUnique;            /* Outer loops generate different values in
-                                ** every row for the ORDER BY columns */
-
-  if( p->i==0 ){
-    nPriorSat = 0;
-    outerObUnique = 1;
-  }else{
-    u32 wsFlags = p->aLevel[p->i-1].plan.wsFlags;
-    nPriorSat = p->aLevel[p->i-1].plan.nOBSat;
-    if( (wsFlags & WHERE_ORDERED)==0 ){
-      /* This loop cannot be ordered unless the next outer loop is
-      ** also ordered */
-      return nPriorSat;
-    }
-    if( OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ){
-      /* Only look at the outer-most loop if the OrderByIdxJoin
-      ** optimization is disabled */
-      return nPriorSat;
-    }
-    testcase( wsFlags & WHERE_OB_UNIQUE );
-    testcase( wsFlags & WHERE_ALL_UNIQUE );
-    outerObUnique = (wsFlags & (WHERE_OB_UNIQUE|WHERE_ALL_UNIQUE))!=0;
-  }
-  pOrderBy = p->pOrderBy;
-  assert( pOrderBy!=0 );
-  if( pIdx->bUnordered ){
-    /* Hash indices (indicated by the "unordered" tag on sqlite_stat1) cannot
-    ** be used for sorting */
-    return nPriorSat;
-  }
-  nTerm = pOrderBy->nExpr;
-  uniqueNotNull = pIdx->onError!=OE_None;
-  assert( nTerm>0 );
-
-  /* Argument pIdx must either point to a 'real' named index structure, 
-  ** or an index structure allocated on the stack by bestBtreeIndex() to
-  ** represent the rowid index that is part of every table.  */
-  assert( pIdx->zName || (pIdx->nColumn==1 && pIdx->aiColumn[0]==-1) );
-
-  /* Match terms of the ORDER BY clause against columns of
-  ** the index.
-  **
-  ** Note that indices have pIdx->nColumn regular columns plus
-  ** one additional column containing the rowid.  The rowid column
-  ** of the index is also allowed to match against the ORDER BY
-  ** clause.
-  */
-  j = nPriorSat;
-  for(i=0,pOBItem=&pOrderBy->a[j]; j<nTerm && i<=pIdx->nColumn; i++){
-    Expr *pOBExpr;          /* The expression of the ORDER BY pOBItem */
-    CollSeq *pColl;         /* The collating sequence of pOBExpr */
-    int termSortOrder;      /* Sort order for this term */
-    int iColumn;            /* The i-th column of the index.  -1 for rowid */
-    int iSortOrder;         /* 1 for DESC, 0 for ASC on the i-th index term */
-    int isEq;               /* Subject to an == or IS NULL constraint */
-    int isMatch;            /* ORDER BY term matches the index term */
-    const char *zColl;      /* Name of collating sequence for i-th index term */
-    WhereTerm *pConstraint; /* A constraint in the WHERE clause */
-
-    /* If the next term of the ORDER BY clause refers to anything other than
-    ** a column in the "base" table, then this index will not be of any
-    ** further use in handling the ORDER BY. */
-    pOBExpr = sqlite3ExprSkipCollate(pOBItem->pExpr);
-    if( pOBExpr->op!=TK_COLUMN || pOBExpr->iTable!=base ){
-      break;
-    }
-
-    /* Find column number and collating sequence for the next entry
-    ** in the index */
-    if( pIdx->zName && i<pIdx->nColumn ){
-      iColumn = pIdx->aiColumn[i];
-      if( iColumn==pIdx->pTable->iPKey ){
-        iColumn = -1;
-      }
-      iSortOrder = pIdx->aSortOrder[i];
-      zColl = pIdx->azColl[i];
-      assert( zColl!=0 );
-    }else{
-      iColumn = -1;
-      iSortOrder = 0;
-      zColl = 0;
-    }
-
-    /* Check to see if the column number and collating sequence of the
-    ** index match the column number and collating sequence of the ORDER BY
-    ** clause entry.  Set isMatch to 1 if they both match. */
-    if( pOBExpr->iColumn==iColumn ){
-      if( zColl ){
-        pColl = sqlite3ExprCollSeq(pParse, pOBItem->pExpr);
-        if( !pColl ) pColl = db->pDfltColl;
-        isMatch = sqlite3StrICmp(pColl->zName, zColl)==0;
-      }else{
-        isMatch = 1;
-      }
-    }else{
-      isMatch = 0;
-    }
-
-    /* termSortOrder is 0 or 1 for whether or not the access loop should
-    ** run forward or backwards (respectively) in order to satisfy this 
-    ** term of the ORDER BY clause. */
-    assert( pOBItem->sortOrder==0 || pOBItem->sortOrder==1 );
-    assert( iSortOrder==0 || iSortOrder==1 );
-    termSortOrder = iSortOrder ^ pOBItem->sortOrder;
-
-    /* If X is the column in the index and ORDER BY clause, check to see
-    ** if there are any X= or X IS NULL constraints in the WHERE clause. */
-    pConstraint = findTerm(p->pWC, base, iColumn, p->notReady,
-                           WO_EQ|WO_ISNULL|WO_IN, pIdx);
-    if( pConstraint==0 ){
-      isEq = 0;
-    }else if( (pConstraint->eOperator & WO_IN)!=0 ){
-      isEq = 0;
-    }else if( (pConstraint->eOperator & WO_ISNULL)!=0 ){
-      uniqueNotNull = 0;
-      isEq = 1;  /* "X IS NULL" means X has only a single value */
-    }else if( pConstraint->prereqRight==0 ){
-      isEq = 1;  /* Constraint "X=constant" means X has only a single value */
-    }else{
-      Expr *pRight = pConstraint->pExpr->pRight;
-      if( pRight->op==TK_COLUMN ){
-        WHERETRACE(("       .. isOrderedColumn(tab=%d,col=%d)",
-                    pRight->iTable, pRight->iColumn));
-        isEq = isOrderedColumn(p, pRight->iTable, pRight->iColumn);
-        WHERETRACE((" -> isEq=%d\n", isEq));
-
-        /* If the constraint is of the form X=Y where Y is an ordered value
-        ** in an outer loop, then make sure the sort order of Y matches the
-        ** sort order required for X. */
-        if( isMatch && isEq>=2 && isEq!=pOBItem->sortOrder+2 ){
-          testcase( isEq==2 );
-          testcase( isEq==3 );
-          break;
-        }
-      }else{
-        isEq = 0;  /* "X=expr" places no ordering constraints on X */
-      }
-    }
-    if( !isMatch ){
-      if( isEq==0 ){
-        break;
-      }else{
-        continue;
-      }
-    }else if( isEq!=1 ){
-      if( sortOrder==2 ){
-        sortOrder = termSortOrder;
-      }else if( termSortOrder!=sortOrder ){
-        break;
-      }
-    }
-    j++;
-    pOBItem++;
-    if( iColumn<0 ){
-      seenRowid = 1;
-      break;
-    }else if( pTab->aCol[iColumn].notNull==0 && isEq!=1 ){
-      testcase( isEq==0 );
-      testcase( isEq==2 );
-      testcase( isEq==3 );
-      uniqueNotNull = 0;
-    }
-  }
-  if( seenRowid ){
-    uniqueNotNull = 1;
-  }else if( uniqueNotNull==0 || i<pIdx->nColumn ){
-    uniqueNotNull = 0;
-  }
-
-  /* If we have not found at least one ORDER BY term that matches the
-  ** index, then show no progress. */
-  if( pOBItem==&pOrderBy->a[nPriorSat] ) return nPriorSat;
-
-  /* Either the outer queries must generate rows where there are no two
-  ** rows with the same values in all ORDER BY columns, or else this
-  ** loop must generate just a single row of output.  Example:  Suppose
-  ** the outer loops generate A=1 and A=1, and this loop generates B=3
-  ** and B=4.  Then without the following test, ORDER BY A,B would 
-  ** generate the wrong order output: 1,3 1,4 1,3 1,4
-  */
-  if( outerObUnique==0 && uniqueNotNull==0 ) return nPriorSat;
-  *pbObUnique = uniqueNotNull;
-
-  /* Return the necessary scan order back to the caller */
-  *pbRev = sortOrder & 1;
-
-  /* If there was an "ORDER BY rowid" term that matched, or it is only
-  ** possible for a single row from this table to match, then skip over
-  ** any additional ORDER BY terms dealing with this table.
-  */
-  if( uniqueNotNull ){
-    /* Advance j over additional ORDER BY terms associated with base */
-    WhereMaskSet *pMS = p->pWC->pMaskSet;
-    Bitmask m = ~getMask(pMS, base);
-    while( j<nTerm && (exprTableUsage(pMS, pOrderBy->a[j].pExpr)&m)==0 ){
-      j++;
-    }
-  }
-  return j;
-}
-
-/*
-** Find the best query plan for accessing a particular table.  Write the
-** best query plan and its cost into the p->cost.
-**
-** The lowest cost plan wins.  The cost is an estimate of the amount of
-** CPU and disk I/O needed to process the requested result.
-** Factors that influence cost include:
-**
-**    *  The estimated number of rows that will be retrieved.  (The
-**       fewer the better.)
-**
-**    *  Whether or not sorting must occur.
-**
-**    *  Whether or not there must be separate lookups in the
-**       index and in the main table.
-**
-** If there was an INDEXED BY clause (pSrc->pIndex) attached to the table in
-** the SQL statement, then this function only considers plans using the 
-** named index. If no such plan is found, then the returned cost is
-** SQLITE_BIG_DBL. If a plan is found that uses the named index, 
-** then the cost is calculated in the usual way.
-**
-** If a NOT INDEXED clause was attached to the table 
-** in the SELECT statement, then no indexes are considered. However, the 
-** selected plan may still take advantage of the built-in rowid primary key
-** index.
-*/
-static void bestBtreeIndex(WhereBestIdx *p){
-  Parse *pParse = p->pParse;  /* The parsing context */
-  WhereClause *pWC = p->pWC;  /* The WHERE clause */
-  struct SrcList_item *pSrc = p->pSrc; /* The FROM clause term to search */
-  int iCur = pSrc->iCursor;   /* The cursor of the table to be accessed */
-  Index *pProbe;              /* An index we are evaluating */
-  Index *pIdx;                /* Copy of pProbe, or zero for IPK index */
-  int eqTermMask;             /* Current mask of valid equality operators */
-  int idxEqTermMask;          /* Index mask of valid equality operators */
-  Index sPk;                  /* A fake index object for the primary key */
-  tRowcnt aiRowEstPk[2];      /* The aiRowEst[] value for the sPk index */
-  int aiColumnPk = -1;        /* The aColumn[] value for the sPk index */
-  int wsFlagMask;             /* Allowed flags in p->cost.plan.wsFlag */
-  int nPriorSat;              /* ORDER BY terms satisfied by outer loops */
-  int nOrderBy;               /* Number of ORDER BY terms */
-  char bSortInit;             /* Initializer for bSort in inner loop */
-  char bDistInit;             /* Initializer for bDist in inner loop */
-
-
-  /* Initialize the cost to a worst-case value */
-  memset(&p->cost, 0, sizeof(p->cost));
-  p->cost.rCost = SQLITE_BIG_DBL;
-
-  /* If the pSrc table is the right table of a LEFT JOIN then we may not
-  ** use an index to satisfy IS NULL constraints on that table.  This is
-  ** because columns might end up being NULL if the table does not match -
-  ** a circumstance which the index cannot help us discover.  Ticket #2177.
-  */
-  if( pSrc->jointype & JT_LEFT ){
-    idxEqTermMask = WO_EQ|WO_IN;
-  }else{
-    idxEqTermMask = WO_EQ|WO_IN|WO_ISNULL;
-  }
-
-  if( pSrc->pIndex ){
-    /* An INDEXED BY clause specifies a particular index to use */
-    pIdx = pProbe = pSrc->pIndex;
-    wsFlagMask = ~(WHERE_ROWID_EQ|WHERE_ROWID_RANGE);
-    eqTermMask = idxEqTermMask;
-  }else{
-    /* There is no INDEXED BY clause.  Create a fake Index object in local
-    ** variable sPk to represent the rowid primary key index.  Make this
-    ** fake index the first in a chain of Index objects with all of the real
-    ** indices to follow */
-    Index *pFirst;                  /* First of real indices on the table */
-    memset(&sPk, 0, sizeof(Index));
-    sPk.nColumn = 1;
-    sPk.aiColumn = &aiColumnPk;
-    sPk.aiRowEst = aiRowEstPk;
-    sPk.onError = OE_Replace;
-    sPk.pTable = pSrc->pTab;
-    aiRowEstPk[0] = pSrc->pTab->nRowEst;
-    aiRowEstPk[1] = 1;
-    pFirst = pSrc->pTab->pIndex;
-    if( pSrc->notIndexed==0 ){
-      /* The real indices of the table are only considered if the
-      ** NOT INDEXED qualifier is omitted from the FROM clause */
-      sPk.pNext = pFirst;
-    }
-    pProbe = &sPk;
-    wsFlagMask = ~(
-        WHERE_COLUMN_IN|WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_RANGE
-    );
-    eqTermMask = WO_EQ|WO_IN;
-    pIdx = 0;
-  }
-
-  nOrderBy = p->pOrderBy ? p->pOrderBy->nExpr : 0;
-  if( p->i ){
-    nPriorSat = p->aLevel[p->i-1].plan.nOBSat;
-    bSortInit = nPriorSat<nOrderBy;
-    bDistInit = 0;
-  }else{
-    nPriorSat = 0;
-    bSortInit = nOrderBy>0;
-    bDistInit = p->pDistinct!=0;
-  }
-
-  /* Loop over all indices looking for the best one to use
-  */
-  for(; pProbe; pIdx=pProbe=pProbe->pNext){
-    const tRowcnt * const aiRowEst = pProbe->aiRowEst;
-    WhereCost pc;               /* Cost of using pProbe */
-    double log10N = (double)1;  /* base-10 logarithm of nRow (inexact) */
-
-    /* The following variables are populated based on the properties of
-    ** index being evaluated. They are then used to determine the expected
-    ** cost and number of rows returned.
-    **
-    **  pc.plan.nEq: 
-    **    Number of equality terms that can be implemented using the index.
-    **    In other words, the number of initial fields in the index that
-    **    are used in == or IN or NOT NULL constraints of the WHERE clause.
-    **
-    **  nInMul:  
-    **    The "in-multiplier". This is an estimate of how many seek operations 
-    **    SQLite must perform on the index in question. For example, if the 
-    **    WHERE clause is:
-    **
-    **      WHERE a IN (1, 2, 3) AND b IN (4, 5, 6)
-    **
-    **    SQLite must perform 9 lookups on an index on (a, b), so nInMul is 
-    **    set to 9. Given the same schema and either of the following WHERE 
-    **    clauses:
-    **
-    **      WHERE a =  1
-    **      WHERE a >= 2
-    **
-    **    nInMul is set to 1.
-    **
-    **    If there exists a WHERE term of the form "x IN (SELECT ...)", then 
-    **    the sub-select is assumed to return 25 rows for the purposes of 
-    **    determining nInMul.
-    **
-    **  bInEst:  
-    **    Set to true if there was at least one "x IN (SELECT ...)" term used 
-    **    in determining the value of nInMul.  Note that the RHS of the
-    **    IN operator must be a SELECT, not a value list, for this variable
-    **    to be true.
-    **
-    **  rangeDiv:
-    **    An estimate of a divisor by which to reduce the search space due
-    **    to inequality constraints.  In the absence of sqlite_stat3 ANALYZE
-    **    data, a single inequality reduces the search space to 1/4rd its
-    **    original size (rangeDiv==4).  Two inequalities reduce the search
-    **    space to 1/16th of its original size (rangeDiv==16).
-    **
-    **  bSort:   
-    **    Boolean. True if there is an ORDER BY clause that will require an 
-    **    external sort (i.e. scanning the index being evaluated will not 
-    **    correctly order records).
-    **
-    **  bDist:
-    **    Boolean. True if there is a DISTINCT clause that will require an 
-    **    external btree.
-    **
-    **  bLookup: 
-    **    Boolean. True if a table lookup is required for each index entry
-    **    visited.  In other words, true if this is not a covering index.
-    **    This is always false for the rowid primary key index of a table.
-    **    For other indexes, it is true unless all the columns of the table
-    **    used by the SELECT statement are present in the index (such an
-    **    index is sometimes described as a covering index).
-    **    For example, given the index on (a, b), the second of the following 
-    **    two queries requires table b-tree lookups in order to find the value
-    **    of column c, but the first does not because columns a and b are
-    **    both available in the index.
-    **
-    **             SELECT a, b    FROM tbl WHERE a = 1;
-    **             SELECT a, b, c FROM tbl WHERE a = 1;
-    */
-    int bInEst = 0;               /* True if "x IN (SELECT...)" seen */
-    int nInMul = 1;               /* Number of distinct equalities to lookup */
-    double rangeDiv = (double)1;  /* Estimated reduction in search space */
-    int nBound = 0;               /* Number of range constraints seen */
-    char bSort = bSortInit;       /* True if external sort required */
-    char bDist = bDistInit;       /* True if index cannot help with DISTINCT */
-    char bLookup = 0;             /* True if not a covering index */
-    WhereTerm *pTerm;             /* A single term of the WHERE clause */
-#ifdef SQLITE_ENABLE_STAT3
-    WhereTerm *pFirstTerm = 0;    /* First term matching the index */
-#endif
-
-    WHERETRACE((
-      "   %s(%s):\n",
-      pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk")
-    ));
-    memset(&pc, 0, sizeof(pc));
-    pc.plan.nOBSat = nPriorSat;
-
-    /* Determine the values of pc.plan.nEq and nInMul */
-    for(pc.plan.nEq=0; pc.plan.nEq<pProbe->nColumn; pc.plan.nEq++){
-      int j = pProbe->aiColumn[pc.plan.nEq];
-      pTerm = findTerm(pWC, iCur, j, p->notReady, eqTermMask, pIdx);
-      if( pTerm==0 ) break;
-      pc.plan.wsFlags |= (WHERE_COLUMN_EQ|WHERE_ROWID_EQ);
-      testcase( pTerm->pWC!=pWC );
-      if( pTerm->eOperator & WO_IN ){
-        Expr *pExpr = pTerm->pExpr;
-        pc.plan.wsFlags |= WHERE_COLUMN_IN;
-        if( ExprHasProperty(pExpr, EP_xIsSelect) ){
-          /* "x IN (SELECT ...)":  Assume the SELECT returns 25 rows */
-          nInMul *= 25;
-          bInEst = 1;
-        }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){
-          /* "x IN (value, value, ...)" */
-          nInMul *= pExpr->x.pList->nExpr;
-        }
-      }else if( pTerm->eOperator & WO_ISNULL ){
-        pc.plan.wsFlags |= WHERE_COLUMN_NULL;
-      }
-#ifdef SQLITE_ENABLE_STAT3
-      if( pc.plan.nEq==0 && pProbe->aSample ) pFirstTerm = pTerm;
-#endif
-      pc.used |= pTerm->prereqRight;
-    }
- 
-    /* If the index being considered is UNIQUE, and there is an equality 
-    ** constraint for all columns in the index, then this search will find
-    ** at most a single row. In this case set the WHERE_UNIQUE flag to 
-    ** indicate this to the caller.
-    **
-    ** Otherwise, if the search may find more than one row, test to see if
-    ** there is a range constraint on indexed column (pc.plan.nEq+1) that
-    ** can be optimized using the index. 
-    */
-    if( pc.plan.nEq==pProbe->nColumn && pProbe->onError!=OE_None ){
-      testcase( pc.plan.wsFlags & WHERE_COLUMN_IN );
-      testcase( pc.plan.wsFlags & WHERE_COLUMN_NULL );
-      if( (pc.plan.wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 ){
-        pc.plan.wsFlags |= WHERE_UNIQUE;
-        if( p->i==0 || (p->aLevel[p->i-1].plan.wsFlags & WHERE_ALL_UNIQUE)!=0 ){
-          pc.plan.wsFlags |= WHERE_ALL_UNIQUE;
-        }
-      }
-    }else if( pProbe->bUnordered==0 ){
-      int j;
-      j = (pc.plan.nEq==pProbe->nColumn ? -1 : pProbe->aiColumn[pc.plan.nEq]);
-      if( findTerm(pWC, iCur, j, p->notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){
-        WhereTerm *pTop, *pBtm;
-        pTop = findTerm(pWC, iCur, j, p->notReady, WO_LT|WO_LE, pIdx);
-        pBtm = findTerm(pWC, iCur, j, p->notReady, WO_GT|WO_GE, pIdx);
-        whereRangeScanEst(pParse, pProbe, pc.plan.nEq, pBtm, pTop, &rangeDiv);
-        if( pTop ){
-          nBound = 1;
-          pc.plan.wsFlags |= WHERE_TOP_LIMIT;
-          pc.used |= pTop->prereqRight;
-          testcase( pTop->pWC!=pWC );
-        }
-        if( pBtm ){
-          nBound++;
-          pc.plan.wsFlags |= WHERE_BTM_LIMIT;
-          pc.used |= pBtm->prereqRight;
-          testcase( pBtm->pWC!=pWC );
-        }
-        pc.plan.wsFlags |= (WHERE_COLUMN_RANGE|WHERE_ROWID_RANGE);
-      }
-    }
-
-    /* If there is an ORDER BY clause and the index being considered will
-    ** naturally scan rows in the required order, set the appropriate flags
-    ** in pc.plan.wsFlags. Otherwise, if there is an ORDER BY clause but
-    ** the index will scan rows in a different order, set the bSort
-    ** variable.  */
-    if( bSort && (pSrc->jointype & JT_LEFT)==0 ){
-      int bRev = 2;
-      int bObUnique = 0;
-      WHERETRACE(("      --> before isSortIndex: nPriorSat=%d\n",nPriorSat));
-      pc.plan.nOBSat = isSortingIndex(p, pProbe, iCur, &bRev, &bObUnique);
-      WHERETRACE(("      --> after  isSortIndex: bRev=%d bObU=%d nOBSat=%d\n",
-                  bRev, bObUnique, pc.plan.nOBSat));
-      if( nPriorSat<pc.plan.nOBSat || (pc.plan.wsFlags & WHERE_ALL_UNIQUE)!=0 ){
-        pc.plan.wsFlags |= WHERE_ORDERED;
-        if( bObUnique ) pc.plan.wsFlags |= WHERE_OB_UNIQUE;
-      }
-      if( nOrderBy==pc.plan.nOBSat ){
-        bSort = 0;
-        pc.plan.wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE;
-      }
-      if( bRev & 1 ) pc.plan.wsFlags |= WHERE_REVERSE;
-    }
-
-    /* If there is a DISTINCT qualifier and this index will scan rows in
-    ** order of the DISTINCT expressions, clear bDist and set the appropriate
-    ** flags in pc.plan.wsFlags. */
-    if( bDist
-     && isDistinctIndex(pParse, pWC, pProbe, iCur, p->pDistinct, pc.plan.nEq)
-     && (pc.plan.wsFlags & WHERE_COLUMN_IN)==0
-    ){
-      bDist = 0;
-      pc.plan.wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_DISTINCT;
-    }
-
-    /* If currently calculating the cost of using an index (not the IPK
-    ** index), determine if all required column data may be obtained without 
-    ** using the main table (i.e. if the index is a covering
-    ** index for this query). If it is, set the WHERE_IDX_ONLY flag in
-    ** pc.plan.wsFlags. Otherwise, set the bLookup variable to true.  */
-    if( pIdx ){
-      Bitmask m = pSrc->colUsed;
-      int j;
-      for(j=0; j<pIdx->nColumn; j++){
-        int x = pIdx->aiColumn[j];
-        if( x<BMS-1 ){
-          m &= ~(((Bitmask)1)<<x);
-        }
-      }
-      if( m==0 ){
-        pc.plan.wsFlags |= WHERE_IDX_ONLY;
-      }else{
-        bLookup = 1;
-      }
-    }
-
-    /*
-    ** Estimate the number of rows of output.  For an "x IN (SELECT...)"
-    ** constraint, do not let the estimate exceed half the rows in the table.
-    */
-    pc.plan.nRow = (double)(aiRowEst[pc.plan.nEq] * nInMul);
-    if( bInEst && pc.plan.nRow*2>aiRowEst[0] ){
-      pc.plan.nRow = aiRowEst[0]/2;
-      nInMul = (int)(pc.plan.nRow / aiRowEst[pc.plan.nEq]);
-    }
-
-#ifdef SQLITE_ENABLE_STAT3
-    /* If the constraint is of the form x=VALUE or x IN (E1,E2,...)
-    ** and we do not think that values of x are unique and if histogram
-    ** data is available for column x, then it might be possible
-    ** to get a better estimate on the number of rows based on
-    ** VALUE and how common that value is according to the histogram.
-    */
-    if( pc.plan.nRow>(double)1 && pc.plan.nEq==1
-     && pFirstTerm!=0 && aiRowEst[1]>1 ){
-      assert( (pFirstTerm->eOperator & (WO_EQ|WO_ISNULL|WO_IN))!=0 );
-      if( pFirstTerm->eOperator & (WO_EQ|WO_ISNULL) ){
-        testcase( pFirstTerm->eOperator & WO_EQ );
-        testcase( pFirstTerm->eOperator & WO_EQUIV );
-        testcase( pFirstTerm->eOperator & WO_ISNULL );
-        whereEqualScanEst(pParse, pProbe, pFirstTerm->pExpr->pRight,
-                          &pc.plan.nRow);
-      }else if( bInEst==0 ){
-        assert( pFirstTerm->eOperator & WO_IN );
-        whereInScanEst(pParse, pProbe, pFirstTerm->pExpr->x.pList,
-                       &pc.plan.nRow);
-      }
-    }
-#endif /* SQLITE_ENABLE_STAT3 */
-
-    /* Adjust the number of output rows and downward to reflect rows
-    ** that are excluded by range constraints.
-    */
-    pc.plan.nRow = pc.plan.nRow/rangeDiv;
-    if( pc.plan.nRow<1 ) pc.plan.nRow = 1;
-
-    /* Experiments run on real SQLite databases show that the time needed
-    ** to do a binary search to locate a row in a table or index is roughly
-    ** log10(N) times the time to move from one row to the next row within
-    ** a table or index.  The actual times can vary, with the size of
-    ** records being an important factor.  Both moves and searches are
-    ** slower with larger records, presumably because fewer records fit
-    ** on one page and hence more pages have to be fetched.
-    **
-    ** The ANALYZE command and the sqlite_stat1 and sqlite_stat3 tables do
-    ** not give us data on the relative sizes of table and index records.
-    ** So this computation assumes table records are about twice as big
-    ** as index records
-    */
-    if( (pc.plan.wsFlags&~(WHERE_REVERSE|WHERE_ORDERED|WHERE_OB_UNIQUE))
-                                                              ==WHERE_IDX_ONLY
-     && (pWC->wctrlFlags & WHERE_ONEPASS_DESIRED)==0
-     && sqlite3GlobalConfig.bUseCis
-     && OptimizationEnabled(pParse->db, SQLITE_CoverIdxScan)
-    ){
-      /* This index is not useful for indexing, but it is a covering index.
-      ** A full-scan of the index might be a little faster than a full-scan
-      ** of the table, so give this case a cost slightly less than a table
-      ** scan. */
-      pc.rCost = aiRowEst[0]*3 + pProbe->nColumn;
-      pc.plan.wsFlags |= WHERE_COVER_SCAN|WHERE_COLUMN_RANGE;
-    }else if( (pc.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){
-      /* The cost of a full table scan is a number of move operations equal
-      ** to the number of rows in the table.
-      **
-      ** We add an additional 4x penalty to full table scans.  This causes
-      ** the cost function to err on the side of choosing an index over
-      ** choosing a full scan.  This 4x full-scan penalty is an arguable
-      ** decision and one which we expect to revisit in the future.  But
-      ** it seems to be working well enough at the moment.
-      */
-      pc.rCost = aiRowEst[0]*4;
-      pc.plan.wsFlags &= ~WHERE_IDX_ONLY;
-      if( pIdx ){
-        pc.plan.wsFlags &= ~WHERE_ORDERED;
-        pc.plan.nOBSat = nPriorSat;
-      }
-    }else{
-      log10N = estLog(aiRowEst[0]);
-      pc.rCost = pc.plan.nRow;
-      if( pIdx ){
-        if( bLookup ){
-          /* For an index lookup followed by a table lookup:
-          **    nInMul index searches to find the start of each index range
-          **  + nRow steps through the index
-          **  + nRow table searches to lookup the table entry using the rowid
-          */
-          pc.rCost += (nInMul + pc.plan.nRow)*log10N;
-        }else{
-          /* For a covering index:
-          **     nInMul index searches to find the initial entry 
-          **   + nRow steps through the index
-          */
-          pc.rCost += nInMul*log10N;
-        }
-      }else{
-        /* For a rowid primary key lookup:
-        **    nInMult table searches to find the initial entry for each range
-        **  + nRow steps through the table
-        */
-        pc.rCost += nInMul*log10N;
-      }
-    }
-
-    /* Add in the estimated cost of sorting the result.  Actual experimental
-    ** measurements of sorting performance in SQLite show that sorting time
-    ** adds C*N*log10(N) to the cost, where N is the number of rows to be 
-    ** sorted and C is a factor between 1.95 and 4.3.  We will split the
-    ** difference and select C of 3.0.
-    */
-    if( bSort ){
-      double m = estLog(pc.plan.nRow*(nOrderBy - pc.plan.nOBSat)/nOrderBy);
-      m *= (double)(pc.plan.nOBSat ? 2 : 3);
-      pc.rCost += pc.plan.nRow*m;
-    }
-    if( bDist ){
-      pc.rCost += pc.plan.nRow*estLog(pc.plan.nRow)*3;
-    }
-
-    /**** Cost of using this index has now been computed ****/
-
-    /* If there are additional constraints on this table that cannot
-    ** be used with the current index, but which might lower the number
-    ** of output rows, adjust the nRow value accordingly.  This only 
-    ** matters if the current index is the least costly, so do not bother
-    ** with this step if we already know this index will not be chosen.
-    ** Also, never reduce the output row count below 2 using this step.
-    **
-    ** It is critical that the notValid mask be used here instead of
-    ** the notReady mask.  When computing an "optimal" index, the notReady
-    ** mask will only have one bit set - the bit for the current table.
-    ** The notValid mask, on the other hand, always has all bits set for
-    ** tables that are not in outer loops.  If notReady is used here instead
-    ** of notValid, then a optimal index that depends on inner joins loops
-    ** might be selected even when there exists an optimal index that has
-    ** no such dependency.
-    */
-    if( pc.plan.nRow>2 && pc.rCost<=p->cost.rCost ){
-      int k;                       /* Loop counter */
-      int nSkipEq = pc.plan.nEq;   /* Number of == constraints to skip */
-      int nSkipRange = nBound;     /* Number of < constraints to skip */
-      Bitmask thisTab;             /* Bitmap for pSrc */
-
-      thisTab = getMask(pWC->pMaskSet, iCur);
-      for(pTerm=pWC->a, k=pWC->nTerm; pc.plan.nRow>2 && k; k--, pTerm++){
-        if( pTerm->wtFlags & TERM_VIRTUAL ) continue;
-        if( (pTerm->prereqAll & p->notValid)!=thisTab ) continue;
-        if( pTerm->eOperator & (WO_EQ|WO_IN|WO_ISNULL) ){
-          if( nSkipEq ){
-            /* Ignore the first pc.plan.nEq equality matches since the index
-            ** has already accounted for these */
-            nSkipEq--;
-          }else{
-            /* Assume each additional equality match reduces the result
-            ** set size by a factor of 10 */
-            pc.plan.nRow /= 10;
-          }
-        }else if( pTerm->eOperator & (WO_LT|WO_LE|WO_GT|WO_GE) ){
-          if( nSkipRange ){
-            /* Ignore the first nSkipRange range constraints since the index
-            ** has already accounted for these */
-            nSkipRange--;
-          }else{
-            /* Assume each additional range constraint reduces the result
-            ** set size by a factor of 3.  Indexed range constraints reduce
-            ** the search space by a larger factor: 4.  We make indexed range
-            ** more selective intentionally because of the subjective 
-            ** observation that indexed range constraints really are more
-            ** selective in practice, on average. */
-            pc.plan.nRow /= 3;
-          }
-        }else if( (pTerm->eOperator & WO_NOOP)==0 ){
-          /* Any other expression lowers the output row count by half */
-          pc.plan.nRow /= 2;
-        }
-      }
-      if( pc.plan.nRow<2 ) pc.plan.nRow = 2;
-    }
-
-
-    WHERETRACE((
-      "      nEq=%d nInMul=%d rangeDiv=%d bSort=%d bLookup=%d wsFlags=0x%08x\n"
-      "      notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f\n"
-      "      used=0x%llx nOBSat=%d\n",
-      pc.plan.nEq, nInMul, (int)rangeDiv, bSort, bLookup, pc.plan.wsFlags,
-      p->notReady, log10N, pc.plan.nRow, pc.rCost, pc.used,
-      pc.plan.nOBSat
-    ));
-
-    /* If this index is the best we have seen so far, then record this
-    ** index and its cost in the p->cost structure.
-    */
-    if( (!pIdx || pc.plan.wsFlags) && compareCost(&pc, &p->cost) ){
-      p->cost = pc;
-      p->cost.plan.wsFlags &= wsFlagMask;
-      p->cost.plan.u.pIdx = pIdx;
-    }
-
-    /* If there was an INDEXED BY clause, then only that one index is
-    ** considered. */
-    if( pSrc->pIndex ) break;
-
-    /* Reset masks for the next index in the loop */
-    wsFlagMask = ~(WHERE_ROWID_EQ|WHERE_ROWID_RANGE);
-    eqTermMask = idxEqTermMask;
-  }
-
-  /* If there is no ORDER BY clause and the SQLITE_ReverseOrder flag
-  ** is set, then reverse the order that the index will be scanned
-  ** in. This is used for application testing, to help find cases
-  ** where application behavior depends on the (undefined) order that
-  ** SQLite outputs rows in in the absence of an ORDER BY clause.  */
-  if( !p->pOrderBy && pParse->db->flags & SQLITE_ReverseOrder ){
-    p->cost.plan.wsFlags |= WHERE_REVERSE;
-  }
-
-  assert( p->pOrderBy || (p->cost.plan.wsFlags&WHERE_ORDERED)==0 );
-  assert( p->cost.plan.u.pIdx==0 || (p->cost.plan.wsFlags&WHERE_ROWID_EQ)==0 );
-  assert( pSrc->pIndex==0 
-       || p->cost.plan.u.pIdx==0 
-       || p->cost.plan.u.pIdx==pSrc->pIndex 
-  );
-
-  WHERETRACE(("   best index is %s cost=%.1f\n",
-         p->cost.plan.u.pIdx ? p->cost.plan.u.pIdx->zName : "ipk",
-         p->cost.rCost));
-  
-  bestOrClauseIndex(p);
-  bestAutomaticIndex(p);
-  p->cost.plan.wsFlags |= eqTermMask;
-}
-
-/*
-** Find the query plan for accessing table pSrc->pTab. Write the
-** best query plan and its cost into the WhereCost object supplied 
-** as the last parameter. This function may calculate the cost of
-** both real and virtual table scans.
-**
-** This function does not take ORDER BY or DISTINCT into account.  Nor
-** does it remember the virtual table query plan.  All it does is compute
-** the cost while determining if an OR optimization is applicable.  The
-** details will be reconsidered later if the optimization is found to be
-** applicable.
-*/
-static void bestIndex(WhereBestIdx *p){
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-  if( IsVirtual(p->pSrc->pTab) ){
-    sqlite3_index_info *pIdxInfo = 0;
-    p->ppIdxInfo = &pIdxInfo;
-    bestVirtualIndex(p);
-    assert( pIdxInfo!=0 || p->pParse->db->mallocFailed );
-    if( pIdxInfo && pIdxInfo->needToFreeIdxStr ){
-      sqlite3_free(pIdxInfo->idxStr);
-    }
-    sqlite3DbFree(p->pParse->db, pIdxInfo);
-  }else
-#endif
-  {
-    bestBtreeIndex(p);
-  }
-}
-
-/*
 ** Disable a term in the WHERE clause.  Except, do not disable the term
 ** if it controls a LEFT OUTER JOIN and it did not originate in the ON
 ** or USING clause of that join.
@@ -108157,9 +107622,6 @@ static void bestIndex(WhereBestIdx *p){
 ** in the ON clause.  The term is disabled in (3) because it is not part
 ** of a LEFT OUTER JOIN.  In (1), the term is not disabled.
 **
-** IMPLEMENTATION-OF: R-24597-58655 No tests are done for terms that are
-** completely satisfied by indices.
-**
 ** Disabling a term causes that term to not be tested in the inner loop
 ** of the join.  Disabling is an optimization.  When terms are satisfied
 ** by indices, we disable them to prevent redundant tests in the inner
@@ -108239,6 +107701,7 @@ static int codeEqualityTerm(
   WhereTerm *pTerm,   /* The term of the WHERE clause to be coded */
   WhereLevel *pLevel, /* The level of the FROM clause we are working on */
   int iEq,            /* Index of the equality term within this level */
+  int bRev,           /* True for reverse-order IN operations */
   int iTarget         /* Attempt to leave results in this register */
 ){
   Expr *pX = pTerm->pExpr;
@@ -108256,14 +107719,13 @@ static int codeEqualityTerm(
     int eType;
     int iTab;
     struct InLoop *pIn;
-    u8 bRev = (pLevel->plan.wsFlags & WHERE_REVERSE)!=0;
+    WhereLoop *pLoop = pLevel->pWLoop;
 
-    if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 
-      && pLevel->plan.u.pIdx->aSortOrder[iEq]
+    if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0
+      && pLoop->u.btree.pIndex!=0
+      && pLoop->u.btree.pIndex->aSortOrder[iEq]
     ){
       testcase( iEq==0 );
-      testcase( iEq==pLevel->plan.u.pIdx->nColumn-1 );
-      testcase( iEq>0 && iEq+1<pLevel->plan.u.pIdx->nColumn );
       testcase( bRev );
       bRev = !bRev;
     }
@@ -108276,7 +107738,8 @@ static int codeEqualityTerm(
     }
     iTab = pX->iTable;
     sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0);
-    assert( pLevel->plan.wsFlags & WHERE_IN_ABLE );
+    assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
+    pLoop->wsFlags |= WHERE_IN_ABLE;
     if( pLevel->u.in.nIn==0 ){
       pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
     }
@@ -108346,29 +107809,31 @@ static int codeEqualityTerm(
 static int codeAllEqualityTerms(
   Parse *pParse,        /* Parsing context */
   WhereLevel *pLevel,   /* Which nested loop of the FROM we are coding */
-  WhereClause *pWC,     /* The WHERE clause */
-  Bitmask notReady,     /* Which parts of FROM have not yet been coded */
+  int bRev,             /* Reverse the order of IN operators */
   int nExtraReg,        /* Number of extra registers to allocate */
   char **pzAff          /* OUT: Set to point to affinity string */
 ){
-  int nEq = pLevel->plan.nEq;   /* The number of == or IN constraints to code */
+  int nEq;                      /* The number of == or IN constraints to code */
   Vdbe *v = pParse->pVdbe;      /* The vm under construction */
   Index *pIdx;                  /* The index being used for this loop */
-  int iCur = pLevel->iTabCur;   /* The cursor of the table */
   WhereTerm *pTerm;             /* A single constraint term */
+  WhereLoop *pLoop;             /* The WhereLoop object */
   int j;                        /* Loop counter */
   int regBase;                  /* Base register */
   int nReg;                     /* Number of registers to allocate */
   char *zAff;                   /* Affinity string to return */
 
   /* This module is only called on query plans that use an index. */
-  assert( pLevel->plan.wsFlags & WHERE_INDEXED );
-  pIdx = pLevel->plan.u.pIdx;
+  pLoop = pLevel->pWLoop;
+  assert( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 );
+  nEq = pLoop->u.btree.nEq;
+  pIdx = pLoop->u.btree.pIndex;
+  assert( pIdx!=0 );
 
   /* Figure out how many memory cells we will need then allocate them.
   */
   regBase = pParse->nMem + 1;
-  nReg = pLevel->plan.nEq + nExtraReg;
+  nReg = pLoop->u.btree.nEq + nExtraReg;
   pParse->nMem += nReg;
 
   zAff = sqlite3DbStrDup(pParse->db, sqlite3IndexAffinityStr(v, pIdx));
@@ -108378,17 +107843,16 @@ static int codeAllEqualityTerms(
 
   /* Evaluate the equality constraints
   */
-  assert( pIdx->nColumn>=nEq );
+  assert( zAff==0 || strlen(zAff)>=nEq );
   for(j=0; j<nEq; j++){
     int r1;
-    int k = pIdx->aiColumn[j];
-    pTerm = findTerm(pWC, iCur, k, notReady, pLevel->plan.wsFlags, pIdx);
-    if( pTerm==0 ) break;
+    pTerm = pLoop->aLTerm[j];
+    assert( pTerm!=0 );
     /* The following true for indices with redundant columns. 
     ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */
     testcase( (pTerm->wtFlags & TERM_CODED)!=0 );
-    testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
-    r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, regBase+j);
+    testcase( pTerm->wtFlags & TERM_VIRTUAL );
+    r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j);
     if( r1!=regBase+j ){
       if( nReg==1 ){
         sqlite3ReleaseTempReg(pParse, regBase);
@@ -108456,31 +107920,31 @@ static void explainAppendTerm(
 ** It is the responsibility of the caller to free the buffer when it is
 ** no longer required.
 */
-static char *explainIndexRange(sqlite3 *db, WhereLevel *pLevel, Table *pTab){
-  WherePlan *pPlan = &pLevel->plan;
-  Index *pIndex = pPlan->u.pIdx;
-  int nEq = pPlan->nEq;
+static char *explainIndexRange(sqlite3 *db, WhereLoop *pLoop, Table *pTab){
+  Index *pIndex = pLoop->u.btree.pIndex;
+  int nEq = pLoop->u.btree.nEq;
   int i, j;
   Column *aCol = pTab->aCol;
   int *aiColumn = pIndex->aiColumn;
   StrAccum txt;
 
-  if( nEq==0 && (pPlan->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
+  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);
   for(i=0; i<nEq; i++){
-    explainAppendTerm(&txt, i, aCol[aiColumn[i]].zName, "=");
+    char *z = (i==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[i]].zName;
+    explainAppendTerm(&txt, i, z, "=");
   }
 
   j = i;
-  if( pPlan->wsFlags&WHERE_BTM_LIMIT ){
+  if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
     char *z = (j==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[j]].zName;
     explainAppendTerm(&txt, i++, z, ">");
   }
-  if( pPlan->wsFlags&WHERE_TOP_LIMIT ){
+  if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
     char *z = (j==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[j]].zName;
     explainAppendTerm(&txt, i, z, "<");
   }
@@ -108503,20 +107967,22 @@ static void explainOneScan(
   u16 wctrlFlags                  /* Flags passed to sqlite3WhereBegin() */
 ){
   if( pParse->explain==2 ){
-    u32 flags = pLevel->plan.wsFlags;
     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 */
-    sqlite3_int64 nRow;           /* Expected number of rows visited by scan */
     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 */
 
+    pLoop = pLevel->pWLoop;
+    flags = pLoop->wsFlags;
     if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return;
 
-    isSearch = (pLevel->plan.nEq>0)
-             || (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
-             || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
+    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");
     if( pItem->pSelect ){
@@ -108528,43 +107994,37 @@ static void explainOneScan(
     if( pItem->zAlias ){
       zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias);
     }
-    if( (flags & WHERE_INDEXED)!=0 ){
-      char *zWhere = explainIndexRange(db, pLevel, pItem->pTab);
-      zMsg = sqlite3MAppendf(db, zMsg, "%s USING %s%sINDEX%s%s%s", zMsg, 
-          ((flags & WHERE_TEMP_INDEX)?"AUTOMATIC ":""),
-          ((flags & WHERE_IDX_ONLY)?"COVERING ":""),
-          ((flags & WHERE_TEMP_INDEX)?"":" "),
-          ((flags & WHERE_TEMP_INDEX)?"": pLevel->plan.u.pIdx->zName),
-          zWhere
-      );
+    if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0
+     && ALWAYS(pLoop->u.btree.pIndex!=0)
+    ){
+      char *zWhere = explainIndexRange(db, pLoop, pItem->pTab);
+      zMsg = sqlite3MAppendf(db, zMsg,
+               ((flags & WHERE_AUTO_INDEX) ? 
+                   "%s USING AUTOMATIC %sINDEX%.0s%s" :
+                   "%s USING %sINDEX %s%s"), 
+               zMsg, ((flags & WHERE_IDX_ONLY) ? "COVERING " : ""),
+               pLoop->u.btree.pIndex->zName, zWhere);
       sqlite3DbFree(db, zWhere);
-    }else if( flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
+    }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
       zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg);
 
-      if( flags&WHERE_ROWID_EQ ){
+      if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
         zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid=?)", zMsg);
       }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
         zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>? AND rowid<?)", zMsg);
       }else if( flags&WHERE_BTM_LIMIT ){
         zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>?)", zMsg);
-      }else if( flags&WHERE_TOP_LIMIT ){
+      }else if( ALWAYS(flags&WHERE_TOP_LIMIT) ){
         zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid<?)", zMsg);
       }
     }
 #ifndef SQLITE_OMIT_VIRTUALTABLE
     else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
-      sqlite3_index_info *pVtabIdx = pLevel->plan.u.pVtabIdx;
       zMsg = sqlite3MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg,
-                  pVtabIdx->idxNum, pVtabIdx->idxStr);
+                  pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
     }
 #endif
-    if( wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX) ){
-      testcase( wctrlFlags & WHERE_ORDERBY_MIN );
-      nRow = 1;
-    }else{
-      nRow = (sqlite3_int64)pLevel->plan.nRow;
-    }
-    zMsg = sqlite3MAppendf(db, zMsg, "%s (~%lld rows)", zMsg, nRow);
+    zMsg = sqlite3MAppendf(db, zMsg, "%s", zMsg);
     sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC);
   }
 }
@@ -108580,7 +108040,6 @@ static void explainOneScan(
 static Bitmask codeOneLoopStart(
   WhereInfo *pWInfo,   /* Complete information about the WHERE clause */
   int iLevel,          /* Which level of pWInfo->a[] should be coded */
-  u16 wctrlFlags,      /* One of the WHERE_* flags defined in sqliteInt.h */
   Bitmask notReady     /* Which tables are currently available */
 ){
   int j, k;            /* Loop counters */
@@ -108589,9 +108048,11 @@ static Bitmask codeOneLoopStart(
   int omitTable;       /* True if we use the index only */
   int bRev;            /* True if we need to scan in reverse order */
   WhereLevel *pLevel;  /* The where level to be coded */
+  WhereLoop *pLoop;    /* The WhereLoop object being coded */
   WhereClause *pWC;    /* Decomposition of the entire WHERE clause */
   WhereTerm *pTerm;               /* A WHERE clause term */
   Parse *pParse;                  /* Parsing context */
+  sqlite3 *db;                    /* Database connection */
   Vdbe *v;                        /* The prepared stmt under constructions */
   struct SrcList_item *pTabItem;  /* FROM clause term being coded */
   int addrBrk;                    /* Jump here to break out of the loop */
@@ -108602,13 +108063,15 @@ static Bitmask codeOneLoopStart(
 
   pParse = pWInfo->pParse;
   v = pParse->pVdbe;
-  pWC = pWInfo->pWC;
+  pWC = &pWInfo->sWC;
+  db = pParse->db;
   pLevel = &pWInfo->a[iLevel];
+  pLoop = pLevel->pWLoop;
   pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
   iCur = pTabItem->iCursor;
-  bRev = (pLevel->plan.wsFlags & WHERE_REVERSE)!=0;
-  omitTable = (pLevel->plan.wsFlags & WHERE_IDX_ONLY)!=0 
-           && (wctrlFlags & WHERE_FORCE_TABLE)==0;
+  bRev = (pWInfo->revMask>>iLevel)&1;
+  omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 
+           && (pWInfo->wctrlFlags & WHERE_FORCE_TABLE)==0;
   VdbeNoopComment((v, "Begin Join Loop %d", iLevel));
 
   /* Create labels for the "break" and "continue" instructions
@@ -108645,47 +108108,37 @@ static Bitmask codeOneLoopStart(
   }else
 
 #ifndef SQLITE_OMIT_VIRTUALTABLE
-  if(  (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
-    /* Case 0:  The table is a virtual-table.  Use the VFilter and VNext
+  if(  (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){
+    /* Case 1:  The table is a virtual-table.  Use the VFilter and VNext
     **          to access the data.
     */
     int iReg;   /* P3 Value for OP_VFilter */
     int addrNotFound;
-    sqlite3_index_info *pVtabIdx = pLevel->plan.u.pVtabIdx;
-    int nConstraint = pVtabIdx->nConstraint;
-    struct sqlite3_index_constraint_usage *aUsage =
-                                                pVtabIdx->aConstraintUsage;
-    const struct sqlite3_index_constraint *aConstraint =
-                                                pVtabIdx->aConstraint;
+    int nConstraint = pLoop->nLTerm;
 
     sqlite3ExprCachePush(pParse);
     iReg = sqlite3GetTempRange(pParse, nConstraint+2);
     addrNotFound = pLevel->addrBrk;
-    for(j=1; j<=nConstraint; j++){
-      for(k=0; k<nConstraint; k++){
-        if( aUsage[k].argvIndex==j ){
-          int iTarget = iReg+j+1;
-          pTerm = &pWC->a[aConstraint[k].iTermOffset];
-          if( pTerm->eOperator & WO_IN ){
-            codeEqualityTerm(pParse, pTerm, pLevel, k, iTarget);
-            addrNotFound = pLevel->addrNxt;
-          }else{
-            sqlite3ExprCode(pParse, pTerm->pExpr->pRight, iTarget);
-          }
-          break;
-        }
+    for(j=0; j<nConstraint; j++){
+      int iTarget = iReg+j+2;
+      pTerm = pLoop->aLTerm[j];
+      if( pTerm==0 ) continue;
+      if( pTerm->eOperator & WO_IN ){
+        codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
+        addrNotFound = pLevel->addrNxt;
+      }else{
+        sqlite3ExprCode(pParse, pTerm->pExpr->pRight, iTarget);
       }
-      if( k==nConstraint ) break;
     }
-    sqlite3VdbeAddOp2(v, OP_Integer, pVtabIdx->idxNum, iReg);
-    sqlite3VdbeAddOp2(v, OP_Integer, j-1, iReg+1);
-    sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg, pVtabIdx->idxStr,
-                      pVtabIdx->needToFreeIdxStr ? P4_MPRINTF : P4_STATIC);
-    pVtabIdx->needToFreeIdxStr = 0;
-    for(j=0; j<nConstraint; j++){
-      if( aUsage[j].omit ){
-        int iTerm = aConstraint[j].iTermOffset;
-        disableTerm(pLevel, &pWC->a[iTerm]);
+    sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg);
+    sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1);
+    sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg,
+                      pLoop->u.vtab.idxStr,
+                      pLoop->u.vtab.needFree ? P4_MPRINTF : P4_STATIC);
+    pLoop->u.vtab.needFree = 0;
+    for(j=0; j<nConstraint && j<16; j++){
+      if( (pLoop->u.vtab.omitMask>>j)&1 ){
+        disableTerm(pLevel, pLoop->aLTerm[j]);
       }
     }
     pLevel->op = OP_VNext;
@@ -108696,19 +108149,22 @@ static Bitmask codeOneLoopStart(
   }else
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
 
-  if( pLevel->plan.wsFlags & WHERE_ROWID_EQ ){
-    /* Case 1:  We can directly reference a single row using an
+  if( (pLoop->wsFlags & WHERE_IPK)!=0
+   && (pLoop->wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_EQ))!=0
+  ){
+    /* Case 2:  We can directly reference a single row using an
     **          equality comparison against the ROWID field.  Or
     **          we reference multiple rows using a "rowid IN (...)"
     **          construct.
     */
+    assert( pLoop->u.btree.nEq==1 );
     iReleaseReg = sqlite3GetTempReg(pParse);
-    pTerm = findTerm(pWC, iCur, -1, notReady, WO_EQ|WO_IN, 0);
+    pTerm = pLoop->aLTerm[0];
     assert( pTerm!=0 );
     assert( pTerm->pExpr!=0 );
     assert( omitTable==0 );
-    testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
-    iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, iReleaseReg);
+    testcase( pTerm->wtFlags & TERM_VIRTUAL );
+    iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
     addrNxt = pLevel->addrNxt;
     sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt);
     sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg);
@@ -108716,8 +108172,10 @@ static Bitmask codeOneLoopStart(
     sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
     VdbeComment((v, "pk"));
     pLevel->op = OP_Noop;
-  }else if( pLevel->plan.wsFlags & WHERE_ROWID_RANGE ){
-    /* Case 2:  We have an inequality comparison against the ROWID field.
+  }else if( (pLoop->wsFlags & WHERE_IPK)!=0
+         && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0
+  ){
+    /* Case 3:  We have an inequality comparison against the ROWID field.
     */
     int testOp = OP_Noop;
     int start;
@@ -108725,8 +108183,11 @@ static Bitmask codeOneLoopStart(
     WhereTerm *pStart, *pEnd;
 
     assert( omitTable==0 );
-    pStart = findTerm(pWC, iCur, -1, notReady, WO_GT|WO_GE, 0);
-    pEnd = findTerm(pWC, iCur, -1, notReady, WO_LT|WO_LE, 0);
+    j = 0;
+    pStart = pEnd = 0;
+    if( pLoop->wsFlags & WHERE_BTM_LIMIT ) pStart = pLoop->aLTerm[j++];
+    if( pLoop->wsFlags & WHERE_TOP_LIMIT ) pEnd = pLoop->aLTerm[j++];
+    assert( pStart!=0 || pEnd!=0 );
     if( bRev ){
       pTerm = pStart;
       pStart = pEnd;
@@ -108749,10 +108210,11 @@ static Bitmask codeOneLoopStart(
       assert( TK_LT==TK_GT+2 );      /*  ... of the TK_xx values... */
       assert( TK_GE==TK_GT+3 );      /*  ... is correcct. */
 
-      testcase( pStart->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
+      assert( (pStart->wtFlags & TERM_VNULL)==0 );
+      testcase( pStart->wtFlags & TERM_VIRTUAL );
       pX = pStart->pExpr;
       assert( pX!=0 );
-      assert( pStart->leftCursor==iCur );
+      testcase( pStart->leftCursor!=iCur ); /* transitive constraints */
       r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
       sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1);
       VdbeComment((v, "pk"));
@@ -108766,8 +108228,9 @@ static Bitmask codeOneLoopStart(
       Expr *pX;
       pX = pEnd->pExpr;
       assert( pX!=0 );
-      assert( pEnd->leftCursor==iCur );
-      testcase( pEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
+      assert( (pEnd->wtFlags & TERM_VNULL)==0 );
+      testcase( pEnd->leftCursor!=iCur ); /* Transitive constraints */
+      testcase( pEnd->wtFlags & TERM_VIRTUAL );
       memEndValue = ++pParse->nMem;
       sqlite3ExprCode(pParse, pX->pRight, memEndValue);
       if( pX->op==TK_LT || pX->op==TK_GT ){
@@ -108781,11 +108244,7 @@ static Bitmask codeOneLoopStart(
     pLevel->op = bRev ? OP_Prev : OP_Next;
     pLevel->p1 = iCur;
     pLevel->p2 = start;
-    if( pStart==0 && pEnd==0 ){
-      pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
-    }else{
-      assert( pLevel->p5==0 );
-    }
+    assert( pLevel->p5==0 );
     if( testOp!=OP_Noop ){
       iRowidReg = iReleaseReg = sqlite3GetTempReg(pParse);
       sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg);
@@ -108793,8 +108252,8 @@ static Bitmask codeOneLoopStart(
       sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg);
       sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL);
     }
-  }else if( pLevel->plan.wsFlags & (WHERE_COLUMN_RANGE|WHERE_COLUMN_EQ) ){
-    /* Case 3: A scan using an index.
+  }else if( pLoop->wsFlags & WHERE_INDEXED ){
+    /* Case 4: A scan using an index.
     **
     **         The WHERE clause may contain zero or more equality 
     **         terms ("==" or "IN" operators) that refer to the N
@@ -108840,8 +108299,8 @@ static Bitmask codeOneLoopStart(
       OP_IdxGE,            /* 1: (end_constraints && !bRev) */
       OP_IdxLT             /* 2: (end_constraints && bRev) */
     };
-    int nEq = pLevel->plan.nEq;  /* Number of == or IN terms */
-    int isMinQuery = 0;          /* If this is an optimized SELECT min(x).. */
+    int nEq = pLoop->u.btree.nEq;  /* Number of == or IN terms */
+    int isMinQuery = 0;            /* If this is an optimized SELECT min(x).. */
     int regBase;                 /* Base register holding constraint values */
     int r1;                      /* Temp register */
     WhereTerm *pRangeStart = 0;  /* Inequality constraint at range start */
@@ -108857,9 +108316,8 @@ static Bitmask codeOneLoopStart(
     char *zStartAff;             /* Affinity for start of range constraint */
     char *zEndAff;               /* Affinity for end of range constraint */
 
-    pIdx = pLevel->plan.u.pIdx;
+    pIdx = pLoop->u.btree.pIndex;
     iIdxCur = pLevel->iIdxCur;
-    k = (nEq==pIdx->nColumn ? -1 : pIdx->aiColumn[nEq]);
 
     /* If this loop satisfies a sort order (pOrderBy) request that 
     ** was passed to this function to implement a "SELECT min(x) ..." 
@@ -108869,8 +108327,8 @@ static Bitmask codeOneLoopStart(
     ** the first one after the nEq equality constraints in the index,
     ** this requires some special handling.
     */
-    if( (wctrlFlags&WHERE_ORDERBY_MIN)!=0
-     && (pLevel->plan.wsFlags&WHERE_ORDERED)
+    if( (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)!=0
+     && (pWInfo->bOBSat!=0)
      && (pIdx->nColumn>nEq)
     ){
       /* assert( pOrderBy->nExpr==1 ); */
@@ -108882,12 +108340,13 @@ static Bitmask codeOneLoopStart(
     /* Find any inequality constraint terms for the start and end 
     ** of the range. 
     */
-    if( pLevel->plan.wsFlags & WHERE_TOP_LIMIT ){
-      pRangeEnd = findTerm(pWC, iCur, k, notReady, (WO_LT|WO_LE), pIdx);
+    j = nEq;
+    if( pLoop->wsFlags & WHERE_BTM_LIMIT ){
+      pRangeStart = pLoop->aLTerm[j++];
       nExtraReg = 1;
     }
-    if( pLevel->plan.wsFlags & WHERE_BTM_LIMIT ){
-      pRangeStart = findTerm(pWC, iCur, k, notReady, (WO_GT|WO_GE), pIdx);
+    if( pLoop->wsFlags & WHERE_TOP_LIMIT ){
+      pRangeEnd = pLoop->aLTerm[j++];
       nExtraReg = 1;
     }
 
@@ -108895,10 +108354,8 @@ static Bitmask codeOneLoopStart(
     ** and store the values of those terms in an array of registers
     ** starting at regBase.
     */
-    regBase = codeAllEqualityTerms(
-        pParse, pLevel, pWC, notReady, nExtraReg, &zStartAff
-    );
-    zEndAff = sqlite3DbStrDup(pParse->db, zStartAff);
+    regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
+    zEndAff = sqlite3DbStrDup(db, zStartAff);
     addrNxt = pLevel->addrNxt;
 
     /* If we are doing a reverse order scan on an ascending index, or
@@ -108911,10 +108368,10 @@ static Bitmask codeOneLoopStart(
       SWAP(WhereTerm *, pRangeEnd, pRangeStart);
     }
 
-    testcase( pRangeStart && pRangeStart->eOperator & WO_LE );
-    testcase( pRangeStart && pRangeStart->eOperator & WO_GE );
-    testcase( pRangeEnd && pRangeEnd->eOperator & WO_LE );
-    testcase( pRangeEnd && pRangeEnd->eOperator & WO_GE );
+    testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 );
+    testcase( pRangeStart && (pRangeStart->eOperator & WO_GE)!=0 );
+    testcase( pRangeEnd && (pRangeEnd->eOperator & WO_LE)!=0 );
+    testcase( pRangeEnd && (pRangeEnd->eOperator & WO_GE)!=0 );
     startEq = !pRangeStart || pRangeStart->eOperator & (WO_LE|WO_GE);
     endEq =   !pRangeEnd || pRangeEnd->eOperator & (WO_LE|WO_GE);
     start_constraints = pRangeStart || nEq>0;
@@ -108939,7 +108396,7 @@ static Bitmask codeOneLoopStart(
         }
       }  
       nConstraint++;
-      testcase( pRangeStart->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
+      testcase( pRangeStart->wtFlags & TERM_VIRTUAL );
     }else if( isMinQuery ){
       sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
       nConstraint++;
@@ -108981,10 +108438,10 @@ static Bitmask codeOneLoopStart(
       }  
       codeApplyAffinity(pParse, regBase, nEq+1, zEndAff);
       nConstraint++;
-      testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
+      testcase( pRangeEnd->wtFlags & TERM_VIRTUAL );
     }
-    sqlite3DbFree(pParse->db, zStartAff);
-    sqlite3DbFree(pParse->db, zEndAff);
+    sqlite3DbFree(db, zStartAff);
+    sqlite3DbFree(db, zEndAff);
 
     /* Top of the loop body */
     pLevel->p2 = sqlite3VdbeCurrentAddr(v);
@@ -109004,9 +108461,9 @@ static Bitmask codeOneLoopStart(
     ** If it is, jump to the next iteration of the loop.
     */
     r1 = sqlite3GetTempReg(pParse);
-    testcase( pLevel->plan.wsFlags & WHERE_BTM_LIMIT );
-    testcase( pLevel->plan.wsFlags & WHERE_TOP_LIMIT );
-    if( (pLevel->plan.wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 ){
+    testcase( pLoop->wsFlags & WHERE_BTM_LIMIT );
+    testcase( pLoop->wsFlags & WHERE_TOP_LIMIT );
+    if( (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 ){
       sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, nEq, r1);
       sqlite3VdbeAddOp2(v, OP_IsNull, r1, addrCont);
     }
@@ -109025,7 +108482,7 @@ static Bitmask codeOneLoopStart(
     /* Record the instruction used to terminate the loop. Disable 
     ** WHERE clause terms made redundant by the index range scan.
     */
-    if( pLevel->plan.wsFlags & WHERE_UNIQUE ){
+    if( pLoop->wsFlags & WHERE_ONEROW ){
       pLevel->op = OP_Noop;
     }else if( bRev ){
       pLevel->op = OP_Prev;
@@ -109033,7 +108490,7 @@ static Bitmask codeOneLoopStart(
       pLevel->op = OP_Next;
     }
     pLevel->p1 = iIdxCur;
-    if( pLevel->plan.wsFlags & WHERE_COVER_SCAN ){
+    if( (pLoop->wsFlags & WHERE_CONSTRAINT)==0 ){
       pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
     }else{
       assert( pLevel->p5==0 );
@@ -109041,8 +108498,8 @@ static Bitmask codeOneLoopStart(
   }else
 
 #ifndef SQLITE_OMIT_OR_OPTIMIZATION
-  if( pLevel->plan.wsFlags & WHERE_MULTI_OR ){
-    /* Case 4:  Two or more separately indexed terms connected by OR
+  if( pLoop->wsFlags & WHERE_MULTI_OR ){
+    /* Case 5:  Two or more separately indexed terms connected by OR
     **
     ** Example:
     **
@@ -109095,7 +108552,7 @@ static Bitmask codeOneLoopStart(
     int ii;                            /* Loop counter */
     Expr *pAndExpr = 0;                /* An ".. AND (...)" expression */
    
-    pTerm = pLevel->plan.u.pTerm;
+    pTerm = pLoop->aLTerm[0];
     assert( pTerm!=0 );
     assert( pTerm->eOperator & WO_OR );
     assert( (pTerm->wtFlags & TERM_ORINFO)!=0 );
@@ -109111,10 +108568,10 @@ static Bitmask codeOneLoopStart(
       int nNotReady;                 /* The number of notReady tables */
       struct SrcList_item *origSrc;     /* Original list of tables */
       nNotReady = pWInfo->nLevel - iLevel - 1;
-      pOrTab = sqlite3StackAllocRaw(pParse->db,
+      pOrTab = sqlite3StackAllocRaw(db,
                             sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0]));
       if( pOrTab==0 ) return notReady;
-      pOrTab->nAlloc = (i16)(nNotReady + 1);
+      pOrTab->nAlloc = (u8)(nNotReady + 1);
       pOrTab->nSrc = pOrTab->nAlloc;
       memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem));
       origSrc = pWInfo->pTabList->a;
@@ -109136,7 +108593,7 @@ static Bitmask codeOneLoopStart(
     ** fall through to the next instruction, just as an OP_Next does if
     ** called on an uninitialized cursor.
     */
-    if( (wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
+    if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
       regRowset = ++pParse->nMem;
       regRowid = ++pParse->nMem;
       sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset);
@@ -109161,11 +108618,12 @@ static Bitmask codeOneLoopStart(
       int iTerm;
       for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
         Expr *pExpr = pWC->a[iTerm].pExpr;
+        if( &pWC->a[iTerm] == pTerm ) continue;
         if( ExprHasProperty(pExpr, EP_FromJoin) ) continue;
-        if( pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_ORINFO) ) continue;
+        if( pWC->a[iTerm].wtFlags & (TERM_ORINFO) ) continue;
         if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
-        pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
-        pAndExpr = sqlite3ExprAnd(pParse->db, pAndExpr, pExpr);
+        pExpr = sqlite3ExprDup(db, pExpr, 0);
+        pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr);
       }
       if( pAndExpr ){
         pAndExpr = sqlite3PExpr(pParse, TK_AND, 0, pAndExpr, 0);
@@ -109185,13 +108643,13 @@ static Bitmask codeOneLoopStart(
         pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
                         WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY |
                         WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY, iCovCur);
-        assert( pSubWInfo || pParse->nErr || pParse->db->mallocFailed );
+        assert( pSubWInfo || pParse->nErr || db->mallocFailed );
         if( pSubWInfo ){
-          WhereLevel *pLvl;
+          WhereLoop *pSubLoop;
           explainOneScan(
               pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
           );
-          if( (wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
+          if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
             int iSet = ((ii==pOrWc->nTerm-1)?-1:ii);
             int r;
             r = sqlite3ExprCodeGetColumn(pParse, pTabItem->pTab, -1, iCur, 
@@ -109220,13 +108678,13 @@ static Bitmask codeOneLoopStart(
           ** pCov to NULL to indicate that no candidate covering index will 
           ** be available.
           */
-          pLvl = &pSubWInfo->a[0];
-          if( (pLvl->plan.wsFlags & WHERE_INDEXED)!=0
-           && (pLvl->plan.wsFlags & WHERE_TEMP_INDEX)==0
-           && (ii==0 || pLvl->plan.u.pIdx==pCov)
+          pSubLoop = pSubWInfo->a[0].pWLoop;
+          assert( (pSubLoop->wsFlags & WHERE_AUTO_INDEX)==0 );
+          if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0
+           && (ii==0 || pSubLoop->u.btree.pIndex==pCov)
           ){
-            assert( pLvl->iIdxCur==iCovCur );
-            pCov = pLvl->plan.u.pIdx;
+            assert( pSubWInfo->a[0].iIdxCur==iCovCur );
+            pCov = pSubLoop->u.btree.pIndex;
           }else{
             pCov = 0;
           }
@@ -109240,42 +108698,37 @@ static Bitmask codeOneLoopStart(
     if( pCov ) pLevel->iIdxCur = iCovCur;
     if( pAndExpr ){
       pAndExpr->pLeft = 0;
-      sqlite3ExprDelete(pParse->db, pAndExpr);
+      sqlite3ExprDelete(db, pAndExpr);
     }
     sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
     sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk);
     sqlite3VdbeResolveLabel(v, iLoopBody);
 
-    if( pWInfo->nLevel>1 ) sqlite3StackFree(pParse->db, pOrTab);
+    if( pWInfo->nLevel>1 ) sqlite3StackFree(db, pOrTab);
     if( !untestedTerms ) disableTerm(pLevel, pTerm);
   }else
 #endif /* SQLITE_OMIT_OR_OPTIMIZATION */
 
   {
-    /* Case 5:  There is no usable index.  We must do a complete
+    /* Case 6:  There is no usable index.  We must do a complete
     **          scan of the entire table.
     */
     static const u8 aStep[] = { OP_Next, OP_Prev };
     static const u8 aStart[] = { OP_Rewind, OP_Last };
     assert( bRev==0 || bRev==1 );
-    assert( omitTable==0 );
     pLevel->op = aStep[bRev];
     pLevel->p1 = iCur;
     pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
     pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
   }
-  newNotReady = notReady & ~getMask(pWC->pMaskSet, iCur);
+  newNotReady = notReady & ~getMask(&pWInfo->sMaskSet, iCur);
 
   /* Insert code to test every subexpression that can be completely
   ** computed using the current set of tables.
-  **
-  ** IMPLEMENTATION-OF: R-49525-50935 Terms that cannot be satisfied through
-  ** the use of indices become tests that are evaluated against each row of
-  ** the relevant input tables.
   */
   for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
     Expr *pE;
-    testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */
+    testcase( pTerm->wtFlags & TERM_VIRTUAL );
     testcase( pTerm->wtFlags & TERM_CODED );
     if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
     if( (pTerm->prereqAll & newNotReady)!=0 ){
@@ -109302,22 +108755,28 @@ static Bitmask codeOneLoopStart(
   ** the implied "t1.a=123" constraint.
   */
   for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
-    Expr *pE;
+    Expr *pE, *pEAlt;
     WhereTerm *pAlt;
-    Expr sEq;
     if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
     if( pTerm->eOperator!=(WO_EQUIV|WO_EQ) ) continue;
     if( pTerm->leftCursor!=iCur ) continue;
+    if( pLevel->iLeftJoin ) continue;
     pE = pTerm->pExpr;
     assert( !ExprHasProperty(pE, EP_FromJoin) );
     assert( (pTerm->prereqRight & newNotReady)!=0 );
     pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady, WO_EQ|WO_IN, 0);
     if( pAlt==0 ) continue;
     if( pAlt->wtFlags & (TERM_CODED) ) continue;
+    testcase( pAlt->eOperator & WO_EQ );
+    testcase( pAlt->eOperator & WO_IN );
     VdbeNoopComment((v, "begin transitive constraint"));
-    sEq = *pAlt->pExpr;
-    sEq.pLeft = pE->pLeft;
-    sqlite3ExprIfFalse(pParse, &sEq, addrCont, SQLITE_JUMPIFNULL);
+    pEAlt = sqlite3StackAllocRaw(db, sizeof(*pEAlt));
+    if( pEAlt ){
+      *pEAlt = *pAlt->pExpr;
+      pEAlt->pLeft = pE->pLeft;
+      sqlite3ExprIfFalse(pParse, pEAlt, addrCont, SQLITE_JUMPIFNULL);
+      sqlite3StackFree(db, pEAlt);
+    }
   }
 
   /* For a LEFT OUTER JOIN, generate code that will record the fact that
@@ -109329,7 +108788,7 @@ static Bitmask codeOneLoopStart(
     VdbeComment((v, "record LEFT JOIN hit"));
     sqlite3ExprCacheClear(pParse);
     for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){
-      testcase( pTerm->wtFlags & TERM_VIRTUAL );  /* IMP: R-30575-11662 */
+      testcase( pTerm->wtFlags & TERM_VIRTUAL );
       testcase( pTerm->wtFlags & TERM_CODED );
       if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
       if( (pTerm->prereqAll & newNotReady)!=0 ){
@@ -109346,47 +108805,1601 @@ static Bitmask codeOneLoopStart(
   return newNotReady;
 }
 
-#if defined(SQLITE_TEST)
+#ifdef WHERETRACE_ENABLED
+/*
+** Print a WhereLoop object for debugging purposes
+*/
+static void whereLoopPrint(WhereLoop *p, SrcList *pTabList){
+  int nb = 1+(pTabList->nSrc+7)/8;
+  struct SrcList_item *pItem = pTabList->a + p->iTab;
+  Table *pTab = pItem->pTab;
+  sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
+                     p->iTab, nb, p->maskSelf, nb, p->prereq);
+  sqlite3DebugPrintf(" %12s",
+                     pItem->zAlias ? pItem->zAlias : pTab->zName);
+  if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
+    if( p->u.btree.pIndex ){
+      const char *zName = p->u.btree.pIndex->zName;
+      if( zName==0 ) zName = "ipk";
+      if( strncmp(zName, "sqlite_autoindex_", 17)==0 ){
+        int i = sqlite3Strlen30(zName) - 1;
+        while( zName[i]!='_' ) i--;
+        zName += i;
+      }
+      sqlite3DebugPrintf(".%-16s %2d", zName, p->u.btree.nEq);
+    }else{
+      sqlite3DebugPrintf("%20s","");
+    }
+  }else{
+    char *z;
+    if( p->u.vtab.idxStr ){
+      z = sqlite3_mprintf("(%d,\"%s\",%x)",
+                p->u.vtab.idxNum, p->u.vtab.idxStr, p->u.vtab.omitMask);
+    }else{
+      z = sqlite3_mprintf("(%d,%x)", p->u.vtab.idxNum, p->u.vtab.omitMask);
+    }
+    sqlite3DebugPrintf(" %-19s", z);
+    sqlite3_free(z);
+  }
+  sqlite3DebugPrintf(" f %04x N %d", p->wsFlags, p->nLTerm);
+  sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut);
+}
+#endif
+
 /*
-** The following variable holds a text description of query plan generated
-** by the most recent call to sqlite3WhereBegin().  Each call to WhereBegin
-** overwrites the previous.  This information is used for testing and
-** analysis only.
+** Convert bulk memory into a valid WhereLoop that can be passed
+** to whereLoopClear harmlessly.
 */
-SQLITE_API char sqlite3_query_plan[BMS*2*40];  /* Text of the join */
-static int nQPlan = 0;              /* Next free slow in _query_plan[] */
+static void whereLoopInit(WhereLoop *p){
+  p->aLTerm = p->aLTermSpace;
+  p->nLTerm = 0;
+  p->nLSlot = ArraySize(p->aLTermSpace);
+  p->wsFlags = 0;
+}
 
-#endif /* SQLITE_TEST */
+/*
+** Clear the WhereLoop.u union.  Leave WhereLoop.pLTerm intact.
+*/
+static void whereLoopClearUnion(sqlite3 *db, WhereLoop *p){
+  if( p->wsFlags & (WHERE_VIRTUALTABLE|WHERE_AUTO_INDEX) ){
+    if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 && p->u.vtab.needFree ){
+      sqlite3_free(p->u.vtab.idxStr);
+      p->u.vtab.needFree = 0;
+      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);
+      sqlite3DbFree(db, p->u.btree.pIndex);
+      p->u.btree.pIndex = 0;
+    }
+  }
+}
+
+/*
+** Deallocate internal memory used by a WhereLoop object
+*/
+static void whereLoopClear(sqlite3 *db, WhereLoop *p){
+  if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm);
+  whereLoopClearUnion(db, p);
+  whereLoopInit(p);
+}
 
+/*
+** Increase the memory allocation for pLoop->aLTerm[] to be at least n.
+*/
+static int whereLoopResize(sqlite3 *db, WhereLoop *p, int n){
+  WhereTerm **paNew;
+  if( p->nLSlot>=n ) return SQLITE_OK;
+  n = (n+7)&~7;
+  paNew = sqlite3DbMallocRaw(db, sizeof(p->aLTerm[0])*n);
+  if( paNew==0 ) return SQLITE_NOMEM;
+  memcpy(paNew, p->aLTerm, sizeof(p->aLTerm[0])*p->nLSlot);
+  if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm);
+  p->aLTerm = paNew;
+  p->nLSlot = n;
+  return SQLITE_OK;
+}
+
+/*
+** Transfer content from the second pLoop into the first.
+*/
+static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){
+  if( whereLoopResize(db, pTo, pFrom->nLTerm) ) return SQLITE_NOMEM;
+  whereLoopClearUnion(db, pTo);
+  memcpy(pTo, pFrom, WHERE_LOOP_XFER_SZ);
+  memcpy(pTo->aLTerm, pFrom->aLTerm, pTo->nLTerm*sizeof(pTo->aLTerm[0]));
+  if( pFrom->wsFlags & WHERE_VIRTUALTABLE ){
+    pFrom->u.vtab.needFree = 0;
+  }else if( (pFrom->wsFlags & WHERE_AUTO_INDEX)!=0 ){
+    pFrom->u.btree.pIndex = 0;
+  }
+  return SQLITE_OK;
+}
+
+/*
+** Delete a WhereLoop object
+*/
+static void whereLoopDelete(sqlite3 *db, WhereLoop *p){
+  whereLoopClear(db, p);
+  sqlite3DbFree(db, p);
+}
 
 /*
 ** Free a WhereInfo structure
 */
 static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
   if( ALWAYS(pWInfo) ){
-    int i;
-    for(i=0; i<pWInfo->nLevel; i++){
-      sqlite3_index_info *pInfo = pWInfo->a[i].pIdxInfo;
-      if( pInfo ){
-        /* assert( pInfo->needToFreeIdxStr==0 || db->mallocFailed ); */
-        if( pInfo->needToFreeIdxStr ){
-          sqlite3_free(pInfo->idxStr);
+    whereClauseClear(&pWInfo->sWC);
+    while( pWInfo->pLoops ){
+      WhereLoop *p = pWInfo->pLoops;
+      pWInfo->pLoops = p->pNextLoop;
+      whereLoopDelete(db, p);
+    }
+    sqlite3DbFree(db, pWInfo);
+  }
+}
+
+/*
+** Insert or replace a WhereLoop entry using the template supplied.
+**
+** An existing WhereLoop entry might be overwritten if the new template
+** is better and has fewer dependencies.  Or the template will be ignored
+** and no insert will occur if an existing WhereLoop is faster and has
+** fewer dependencies than the template.  Otherwise a new WhereLoop is
+** added based on the template.
+**
+** If pBuilder->pOrSet is not NULL then we only care about only the
+** prerequisites and rRun and nOut costs of the N best loops.  That
+** information is gathered in the pBuilder->pOrSet object.  This special
+** processing mode is used only for OR clause processing.
+**
+** When accumulating multiple loops (when pBuilder->pOrSet is NULL) we
+** still might overwrite similar loops with the new template if the
+** template is better.  Loops may be overwritten if the following 
+** conditions are met:
+**
+**    (1)  They have the same iTab.
+**    (2)  They have the same iSortIdx.
+**    (3)  The template has same or fewer dependencies than the current loop
+**    (4)  The template has the same or lower cost than the current loop
+**    (5)  The template uses more terms of the same index but has no additional
+**         dependencies          
+*/
+static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
+  WhereLoop **ppPrev, *p, *pNext = 0;
+  WhereInfo *pWInfo = pBuilder->pWInfo;
+  sqlite3 *db = pWInfo->pParse->db;
+
+  /* If pBuilder->pOrSet is defined, then only keep track of the costs
+  ** and prereqs.
+  */
+  if( pBuilder->pOrSet!=0 ){
+#if WHERETRACE_ENABLED
+    u16 n = pBuilder->pOrSet->n;
+    int x =
+#endif
+    whereOrInsert(pBuilder->pOrSet, pTemplate->prereq, pTemplate->rRun,
+                                    pTemplate->nOut);
+#if WHERETRACE_ENABLED
+    if( sqlite3WhereTrace & 0x8 ){
+      sqlite3DebugPrintf(x?"   or-%d:  ":"   or-X:  ", n);
+      whereLoopPrint(pTemplate, pWInfo->pTabList);
+    }
+#endif
+    return SQLITE_OK;
+  }
+
+  /* Search for an existing WhereLoop to overwrite, or which takes
+  ** priority over pTemplate.
+  */
+  for(ppPrev=&pWInfo->pLoops, p=*ppPrev; p; ppPrev=&p->pNextLoop, p=*ppPrev){
+    if( p->iTab!=pTemplate->iTab || p->iSortIdx!=pTemplate->iSortIdx ){
+      /* If either the iTab or iSortIdx values for two WhereLoop are different
+      ** then those WhereLoops need to be considered separately.  Neither is
+      ** a candidate to replace the other. */
+      continue;
+    }
+    /* In the current implementation, the rSetup value is either zero
+    ** or the cost of building an automatic index (NlogN) and the NlogN
+    ** is the same for compatible WhereLoops. */
+    assert( p->rSetup==0 || pTemplate->rSetup==0 
+                 || p->rSetup==pTemplate->rSetup );
+
+    /* whereLoopAddBtree() always generates and inserts the automatic index
+    ** case first.  Hence compatible candidate WhereLoops never have a larger
+    ** rSetup. Call this SETUP-INVARIANT */
+    assert( p->rSetup>=pTemplate->rSetup );
+
+    if( (p->prereq & pTemplate->prereq)==p->prereq
+     && p->rSetup<=pTemplate->rSetup
+     && p->rRun<=pTemplate->rRun
+    ){
+      /* This branch taken when p is equal or better than pTemplate in 
+      ** all of (1) dependences (2) setup-cost, and (3) run-cost. */
+      assert( p->rSetup==pTemplate->rSetup );
+      if( p->nLTerm<pTemplate->nLTerm
+       && (p->wsFlags & WHERE_INDEXED)!=0
+       && (pTemplate->wsFlags & WHERE_INDEXED)!=0
+       && p->u.btree.pIndex==pTemplate->u.btree.pIndex
+       && p->prereq==pTemplate->prereq
+      ){
+        /* Overwrite an existing WhereLoop with an similar one that uses
+        ** more terms of the index */
+        pNext = p->pNextLoop;
+        break;
+      }else{
+        /* pTemplate is not helpful.
+        ** Return without changing or adding anything */
+        goto whereLoopInsert_noop;
+      }
+    }
+    if( (p->prereq & pTemplate->prereq)==pTemplate->prereq
+     && p->rRun>=pTemplate->rRun
+     && ALWAYS(p->rSetup>=pTemplate->rSetup) /* See SETUP-INVARIANT above */
+    ){
+      /* Overwrite an existing WhereLoop with a better one: one that is
+      ** better at one of (1) dependences, (2) setup-cost, or (3) run-cost
+      ** and is no worse in any of those categories. */
+      pNext = p->pNextLoop;
+      break;
+    }
+  }
+
+  /* If we reach this point it means that either p[] should be overwritten
+  ** with pTemplate[] if p[] exists, or if p==NULL then allocate a new
+  ** WhereLoop and insert it.
+  */
+#if WHERETRACE_ENABLED
+  if( sqlite3WhereTrace & 0x8 ){
+    if( p!=0 ){
+      sqlite3DebugPrintf("ins-del:  ");
+      whereLoopPrint(p, pWInfo->pTabList);
+    }
+    sqlite3DebugPrintf("ins-new:  ");
+    whereLoopPrint(pTemplate, pWInfo->pTabList);
+  }
+#endif
+  if( p==0 ){
+    p = sqlite3DbMallocRaw(db, sizeof(WhereLoop));
+    if( p==0 ) return SQLITE_NOMEM;
+    whereLoopInit(p);
+  }
+  whereLoopXfer(db, p, pTemplate);
+  p->pNextLoop = pNext;
+  *ppPrev = p;
+  if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
+    Index *pIndex = p->u.btree.pIndex;
+    if( pIndex && pIndex->tnum==0 ){
+      p->u.btree.pIndex = 0;
+    }
+  }
+  return SQLITE_OK;
+
+  /* Jump here if the insert is a no-op */
+whereLoopInsert_noop:
+#if WHERETRACE_ENABLED
+  if( sqlite3WhereTrace & 0x8 ){
+    sqlite3DebugPrintf("ins-noop: ");
+    whereLoopPrint(pTemplate, pWInfo->pTabList);
+  }
+#endif
+  return SQLITE_OK;  
+}
+
+/*
+** We have so far matched pBuilder->pNew->u.btree.nEq terms of the index pIndex.
+** Try to match one more.
+**
+** If pProbe->tnum==0, that means pIndex is a fake index used for the
+** INTEGER PRIMARY KEY.
+*/
+static int whereLoopAddBtreeIndex(
+  WhereLoopBuilder *pBuilder,     /* The WhereLoop factory */
+  struct SrcList_item *pSrc,      /* FROM clause term being analyzed */
+  Index *pProbe,                  /* An index on pSrc */
+  WhereCost nInMul                /* log(Number of iterations due to IN) */
+){
+  WhereInfo *pWInfo = pBuilder->pWInfo;  /* WHERE analyse context */
+  Parse *pParse = pWInfo->pParse;        /* Parsing context */
+  sqlite3 *db = pParse->db;       /* Database connection malloc context */
+  WhereLoop *pNew;                /* Template WhereLoop under construction */
+  WhereTerm *pTerm;               /* A WhereTerm under consideration */
+  int opMask;                     /* Valid operators for constraints */
+  WhereScan scan;                 /* Iterator for WHERE terms */
+  Bitmask saved_prereq;           /* Original value of pNew->prereq */
+  u16 saved_nLTerm;               /* Original value of pNew->nLTerm */
+  int saved_nEq;                  /* Original value of pNew->u.btree.nEq */
+  u32 saved_wsFlags;              /* Original value of pNew->wsFlags */
+  WhereCost saved_nOut;           /* Original value of pNew->nOut */
+  int iCol;                       /* Index of the column in the table */
+  int rc = SQLITE_OK;             /* Return code */
+  WhereCost nRowEst;              /* Estimated index selectivity */
+  WhereCost rLogSize;             /* Logarithm of table size */
+  WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */
+
+  pNew = pBuilder->pNew;
+  if( db->mallocFailed ) return SQLITE_NOMEM;
+
+  assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 );
+  assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
+  if( pNew->wsFlags & WHERE_BTM_LIMIT ){
+    opMask = WO_LT|WO_LE;
+  }else if( pProbe->tnum<=0 || (pSrc->jointype & JT_LEFT)!=0 ){
+    opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE;
+  }else{
+    opMask = WO_EQ|WO_IN|WO_ISNULL|WO_GT|WO_GE|WO_LT|WO_LE;
+  }
+  if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
+
+  assert( pNew->u.btree.nEq<=pProbe->nColumn );
+  if( pNew->u.btree.nEq < pProbe->nColumn ){
+    iCol = pProbe->aiColumn[pNew->u.btree.nEq];
+    nRowEst = whereCost(pProbe->aiRowEst[pNew->u.btree.nEq+1]);
+    if( nRowEst==0 && pProbe->onError==OE_None ) nRowEst = 1;
+  }else{
+    iCol = -1;
+    nRowEst = 0;
+  }
+  pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, iCol,
+                        opMask, pProbe);
+  saved_nEq = pNew->u.btree.nEq;
+  saved_nLTerm = pNew->nLTerm;
+  saved_wsFlags = pNew->wsFlags;
+  saved_prereq = pNew->prereq;
+  saved_nOut = pNew->nOut;
+  pNew->rSetup = 0;
+  rLogSize = estLog(whereCost(pProbe->aiRowEst[0]));
+  for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
+    int nIn = 0;
+    if( pTerm->prereqRight & pNew->maskSelf ) continue;
+    if( (pTerm->eOperator==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0)
+     && (iCol<0 || pSrc->pTab->aCol[iCol].notNull)
+    ){
+      continue; /* ignore IS [NOT] NULL constraints on NOT NULL columns */
+    }
+    pNew->wsFlags = saved_wsFlags;
+    pNew->u.btree.nEq = saved_nEq;
+    pNew->nLTerm = saved_nLTerm;
+    if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */
+    pNew->aLTerm[pNew->nLTerm++] = pTerm;
+    pNew->prereq = (saved_prereq | pTerm->prereqRight) & ~pNew->maskSelf;
+    pNew->rRun = rLogSize; /* Baseline cost is log2(N).  Adjustments below */
+    if( pTerm->eOperator & WO_IN ){
+      Expr *pExpr = pTerm->pExpr;
+      pNew->wsFlags |= WHERE_COLUMN_IN;
+      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+        /* "x IN (SELECT ...)":  TUNING: the SELECT returns 25 rows */
+        nIn = 46;  assert( 46==whereCost(25) );
+      }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){
+        /* "x IN (value, value, ...)" */
+        nIn = whereCost(pExpr->x.pList->nExpr);
+      }
+      pNew->rRun += nIn;
+      pNew->u.btree.nEq++;
+      pNew->nOut = nRowEst + nInMul + nIn;
+    }else if( pTerm->eOperator & (WO_EQ) ){
+      assert( (pNew->wsFlags & (WHERE_COLUMN_NULL|WHERE_COLUMN_IN))!=0
+                  || nInMul==0 );
+      pNew->wsFlags |= WHERE_COLUMN_EQ;
+      if( iCol<0  
+       || (pProbe->onError!=OE_None && nInMul==0
+           && pNew->u.btree.nEq==pProbe->nColumn-1)
+      ){
+        assert( (pNew->wsFlags & WHERE_COLUMN_IN)==0 || iCol<0 );
+        pNew->wsFlags |= WHERE_ONEROW;
+      }
+      pNew->u.btree.nEq++;
+      pNew->nOut = nRowEst + nInMul;
+    }else if( pTerm->eOperator & (WO_ISNULL) ){
+      pNew->wsFlags |= WHERE_COLUMN_NULL;
+      pNew->u.btree.nEq++;
+      /* TUNING: IS NULL selects 2 rows */
+      nIn = 10;  assert( 10==whereCost(2) );
+      pNew->nOut = nRowEst + nInMul + nIn;
+    }else if( pTerm->eOperator & (WO_GT|WO_GE) ){
+      testcase( pTerm->eOperator & WO_GT );
+      testcase( pTerm->eOperator & WO_GE );
+      pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT;
+      pBtm = pTerm;
+      pTop = 0;
+    }else{
+      assert( pTerm->eOperator & (WO_LT|WO_LE) );
+      testcase( pTerm->eOperator & WO_LT );
+      testcase( pTerm->eOperator & WO_LE );
+      pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT;
+      pTop = pTerm;
+      pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ?
+                     pNew->aLTerm[pNew->nLTerm-2] : 0;
+    }
+    if( pNew->wsFlags & WHERE_COLUMN_RANGE ){
+      /* Adjust nOut and rRun for STAT3 range values */
+      WhereCost rDiv;
+      whereRangeScanEst(pParse, pProbe, pNew->u.btree.nEq,
+                        pBtm, pTop, &rDiv);
+      pNew->nOut = saved_nOut>rDiv+10 ? saved_nOut - rDiv : 10;
+    }
+#ifdef SQLITE_ENABLE_STAT3
+    if( pNew->u.btree.nEq==1 && pProbe->nSample
+     &&  OptimizationEnabled(db, SQLITE_Stat3) ){
+      tRowcnt nOut = 0;
+      if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))!=0 ){
+        testcase( pTerm->eOperator & WO_EQ );
+        testcase( pTerm->eOperator & WO_ISNULL );
+        rc = whereEqualScanEst(pParse, pProbe, pTerm->pExpr->pRight, &nOut);
+      }else if( (pTerm->eOperator & WO_IN)
+             &&  !ExprHasProperty(pTerm->pExpr, EP_xIsSelect)  ){
+        rc = whereInScanEst(pParse, pProbe, pTerm->pExpr->x.pList, &nOut);
+      }
+      assert( nOut==0 || rc==SQLITE_OK );
+      if( nOut ) pNew->nOut = whereCost(nOut);
+    }
+#endif
+    if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){
+      /* Each row involves a step of the index, then a binary search of
+      ** the main table */
+      pNew->rRun =  whereCostAdd(pNew->rRun, rLogSize>27 ? rLogSize-17 : 10);
+    }
+    /* Step cost for each output row */
+    pNew->rRun = whereCostAdd(pNew->rRun, pNew->nOut);
+    /* TBD: Adjust nOut for additional constraints */
+    rc = whereLoopInsert(pBuilder, pNew);
+    if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0
+     && pNew->u.btree.nEq<(pProbe->nColumn + (pProbe->zName!=0))
+    ){
+      whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn);
+    }
+  }
+  pNew->prereq = saved_prereq;
+  pNew->u.btree.nEq = saved_nEq;
+  pNew->wsFlags = saved_wsFlags;
+  pNew->nOut = saved_nOut;
+  pNew->nLTerm = saved_nLTerm;
+  return rc;
+}
+
+/*
+** Return True if it is possible that pIndex might be useful in
+** implementing the ORDER BY clause in pBuilder.
+**
+** Return False if pBuilder does not contain an ORDER BY clause or
+** if there is no way for pIndex to be useful in implementing that
+** ORDER BY clause.
+*/
+static int indexMightHelpWithOrderBy(
+  WhereLoopBuilder *pBuilder,
+  Index *pIndex,
+  int iCursor
+){
+  ExprList *pOB;
+  int ii, jj;
+
+  if( pIndex->bUnordered ) return 0;
+  if( (pOB = pBuilder->pWInfo->pOrderBy)==0 ) return 0;
+  for(ii=0; ii<pOB->nExpr; ii++){
+    Expr *pExpr = sqlite3ExprSkipCollate(pOB->a[ii].pExpr);
+    if( pExpr->op!=TK_COLUMN ) return 0;
+    if( pExpr->iTable==iCursor ){
+      for(jj=0; jj<pIndex->nColumn; jj++){
+        if( pExpr->iColumn==pIndex->aiColumn[jj] ) return 1;
+      }
+    }
+  }
+  return 0;
+}
+
+/*
+** Return a bitmask where 1s indicate that the corresponding column of
+** the table is used by an index.  Only the first 63 columns are considered.
+*/
+static Bitmask columnsInIndex(Index *pIdx){
+  Bitmask m = 0;
+  int j;
+  for(j=pIdx->nColumn-1; j>=0; j--){
+    int x = pIdx->aiColumn[j];
+    assert( x>=0 );
+    testcase( x==BMS-1 );
+    testcase( x==BMS-2 );
+    if( x<BMS-1 ) m |= MASKBIT(x);
+  }
+  return m;
+}
+
+/* Check to see if a partial index with pPartIndexWhere can be used
+** in the current query.  Return true if it can be and false if not.
+*/
+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;
+  }
+  return 0;
+}
+
+/*
+** Add all WhereLoop objects for a single table of the join where the table
+** is idenfied by pBuilder->pNew->iTab.  That table is guaranteed to be
+** a b-tree table, not a virtual table.
+*/
+static int whereLoopAddBtree(
+  WhereLoopBuilder *pBuilder, /* WHERE clause information */
+  Bitmask mExtra              /* Extra prerequesites for using this table */
+){
+  WhereInfo *pWInfo;          /* WHERE analysis context */
+  Index *pProbe;              /* An index we are evaluating */
+  Index sPk;                  /* A fake index object for the primary key */
+  tRowcnt aiRowEstPk[2];      /* The aiRowEst[] value for the sPk index */
+  int aiColumnPk = -1;        /* The aColumn[] value for the sPk index */
+  SrcList *pTabList;          /* The FROM clause */
+  struct SrcList_item *pSrc;  /* The FROM clause btree term to add */
+  WhereLoop *pNew;            /* Template WhereLoop object */
+  int rc = SQLITE_OK;         /* Return code */
+  int iSortIdx = 1;           /* Index number */
+  int b;                      /* A boolean value */
+  WhereCost rSize;            /* number of rows in the table */
+  WhereCost rLogSize;         /* Logarithm of the number of rows in the table */
+  WhereClause *pWC;           /* The parsed WHERE clause */
+  
+  pNew = pBuilder->pNew;
+  pWInfo = pBuilder->pWInfo;
+  pTabList = pWInfo->pTabList;
+  pSrc = pTabList->a + pNew->iTab;
+  pWC = pBuilder->pWC;
+  assert( !IsVirtual(pSrc->pTab) );
+
+  if( pSrc->pIndex ){
+    /* An INDEXED BY clause specifies a particular index to use */
+    pProbe = pSrc->pIndex;
+  }else{
+    /* There is no INDEXED BY clause.  Create a fake Index object in local
+    ** variable sPk to represent the rowid primary key index.  Make this
+    ** fake index the first in a chain of Index objects with all of the real
+    ** indices to follow */
+    Index *pFirst;                  /* First of real indices on the table */
+    memset(&sPk, 0, sizeof(Index));
+    sPk.nColumn = 1;
+    sPk.aiColumn = &aiColumnPk;
+    sPk.aiRowEst = aiRowEstPk;
+    sPk.onError = OE_Replace;
+    sPk.pTable = pSrc->pTab;
+    aiRowEstPk[0] = pSrc->pTab->nRowEst;
+    aiRowEstPk[1] = 1;
+    pFirst = pSrc->pTab->pIndex;
+    if( pSrc->notIndexed==0 ){
+      /* The real indices of the table are only considered if the
+      ** NOT INDEXED qualifier is omitted from the FROM clause */
+      sPk.pNext = pFirst;
+    }
+    pProbe = &sPk;
+  }
+  rSize = whereCost(pSrc->pTab->nRowEst);
+  rLogSize = estLog(rSize);
+
+#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
+  /* Automatic indexes */
+  if( !pBuilder->pOrSet
+   && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
+   && pSrc->pIndex==0
+   && !pSrc->viaCoroutine
+   && !pSrc->notIndexed
+   && !pSrc->isCorrelated
+  ){
+    /* Generate auto-index WhereLoops */
+    WhereTerm *pTerm;
+    WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
+    for(pTerm=pWC->a; rc==SQLITE_OK && pTerm<pWCEnd; pTerm++){
+      if( pTerm->prereqRight & pNew->maskSelf ) continue;
+      if( termCanDriveIndex(pTerm, pSrc, 0) ){
+        pNew->u.btree.nEq = 1;
+        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==whereCost(7) );
+        /* 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
+        ** not be unreasonable to make this value much larger. */
+        pNew->nOut = 43;  assert( 43==whereCost(20) );
+        pNew->rRun = whereCostAdd(rLogSize,pNew->nOut);
+        pNew->wsFlags = WHERE_AUTO_INDEX;
+        pNew->prereq = mExtra | pTerm->prereqRight;
+        rc = whereLoopInsert(pBuilder, pNew);
+      }
+    }
+  }
+#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */
+
+  /* Loop over all indices
+  */
+  for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){
+    if( pProbe->pPartIdxWhere!=0
+     && !whereUsablePartialIndex(pNew->iTab, pWC, pProbe->pPartIdxWhere) ){
+      continue;  /* Partial index inappropriate for this query */
+    }
+    pNew->u.btree.nEq = 0;
+    pNew->nLTerm = 0;
+    pNew->iSortIdx = 0;
+    pNew->rSetup = 0;
+    pNew->prereq = mExtra;
+    pNew->nOut = rSize;
+    pNew->u.btree.pIndex = pProbe;
+    b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor);
+    /* The ONEPASS_DESIRED flags never occurs together with ORDER BY */
+    assert( (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || b==0 );
+    if( pProbe->tnum<=0 ){
+      /* Integer primary key index */
+      pNew->wsFlags = WHERE_IPK;
+
+      /* Full table scan */
+      pNew->iSortIdx = b ? iSortIdx : 0;
+      /* TUNING: Cost of full table scan is 3*(N + log2(N)).
+      **  +  The extra 3 factor is to encourage the use of indexed lookups
+      **     over full scans.  A smaller constant 2 is used for covering
+      **     index scans so that a covering index scan will be favored over
+      **     a table scan. */
+      pNew->rRun = whereCostAdd(rSize,rLogSize) + 16;
+      rc = whereLoopInsert(pBuilder, pNew);
+      if( rc ) break;
+    }else{
+      Bitmask m = pSrc->colUsed & ~columnsInIndex(pProbe);
+      pNew->wsFlags = (m==0) ? (WHERE_IDX_ONLY|WHERE_INDEXED) : WHERE_INDEXED;
+
+      /* Full scan via index */
+      if( b
+       || ( m==0
+         && pProbe->bUnordered==0
+         && (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0
+         && sqlite3GlobalConfig.bUseCis
+         && OptimizationEnabled(pWInfo->pParse->db, SQLITE_CoverIdxScan)
+          )
+      ){
+        pNew->iSortIdx = b ? iSortIdx : 0;
+        if( m==0 ){
+          /* TUNING: Cost of a covering index scan is 2*(N + log2(N)).
+          **  +  The extra 2 factor is to encourage the use of indexed lookups
+          **     over index scans.  A table scan uses a factor of 3 so that
+          **     index scans are favored over table scans.
+          **  +  If this covering index might also help satisfy the ORDER BY
+          **     clause, then the cost is fudged down slightly so that this
+          **     index is favored above other indices that have no hope of
+          **     helping with the ORDER BY. */
+          pNew->rRun = 10 + whereCostAdd(rSize,rLogSize) - b;
+        }else{
+          assert( b!=0 ); 
+          /* TUNING: Cost of scanning a non-covering index is (N+1)*log2(N)
+          ** which we will simplify to just N*log2(N) */
+          pNew->rRun = rSize + rLogSize;
         }
-        sqlite3DbFree(db, pInfo);
+        rc = whereLoopInsert(pBuilder, pNew);
+        if( rc ) break;
       }
-      if( pWInfo->a[i].plan.wsFlags & WHERE_TEMP_INDEX ){
-        Index *pIdx = pWInfo->a[i].plan.u.pIdx;
-        if( pIdx ){
-          sqlite3DbFree(db, pIdx->zColAff);
-          sqlite3DbFree(db, pIdx);
+    }
+    rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0);
+
+    /* If there was an INDEXED BY clause, then only that one index is
+    ** considered. */
+    if( pSrc->pIndex ) break;
+  }
+  return rc;
+}
+
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+/*
+** Add all WhereLoop objects for a table of the join identified by
+** pBuilder->pNew->iTab.  That table is guaranteed to be a virtual table.
+*/
+static int whereLoopAddVirtual(
+  WhereLoopBuilder *pBuilder   /* WHERE clause information */
+){
+  WhereInfo *pWInfo;           /* WHERE analysis context */
+  Parse *pParse;               /* The parsing context */
+  WhereClause *pWC;            /* The WHERE clause */
+  struct SrcList_item *pSrc;   /* The FROM clause term to search */
+  Table *pTab;
+  sqlite3 *db;
+  sqlite3_index_info *pIdxInfo;
+  struct sqlite3_index_constraint *pIdxCons;
+  struct sqlite3_index_constraint_usage *pUsage;
+  WhereTerm *pTerm;
+  int i, j;
+  int iTerm, mxTerm;
+  int nConstraint;
+  int seenIn = 0;              /* True if an IN operator is seen */
+  int seenVar = 0;             /* True if a non-constant constraint is seen */
+  int iPhase;                  /* 0: const w/o IN, 1: const, 2: no IN,  2: IN */
+  WhereLoop *pNew;
+  int rc = SQLITE_OK;
+
+  pWInfo = pBuilder->pWInfo;
+  pParse = pWInfo->pParse;
+  db = pParse->db;
+  pWC = pBuilder->pWC;
+  pNew = pBuilder->pNew;
+  pSrc = &pWInfo->pTabList->a[pNew->iTab];
+  pTab = pSrc->pTab;
+  assert( IsVirtual(pTab) );
+  pIdxInfo = allocateIndexInfo(pParse, pWC, pSrc, pBuilder->pOrderBy);
+  if( pIdxInfo==0 ) return SQLITE_NOMEM;
+  pNew->prereq = 0;
+  pNew->rSetup = 0;
+  pNew->wsFlags = WHERE_VIRTUALTABLE;
+  pNew->nLTerm = 0;
+  pNew->u.vtab.needFree = 0;
+  pUsage = pIdxInfo->aConstraintUsage;
+  nConstraint = pIdxInfo->nConstraint;
+  if( whereLoopResize(db, pNew, nConstraint) ){
+    sqlite3DbFree(db, pIdxInfo);
+    return SQLITE_NOMEM;
+  }
+
+  for(iPhase=0; iPhase<=3; iPhase++){
+    if( !seenIn && (iPhase&1)!=0 ){
+      iPhase++;
+      if( iPhase>3 ) break;
+    }
+    if( !seenVar && iPhase>1 ) break;
+    pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
+    for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
+      j = pIdxCons->iTermOffset;
+      pTerm = &pWC->a[j];
+      switch( iPhase ){
+        case 0:    /* Constants without IN operator */
+          pIdxCons->usable = 0;
+          if( (pTerm->eOperator & WO_IN)!=0 ){
+            seenIn = 1;
+          }
+          if( pTerm->prereqRight!=0 ){
+            seenVar = 1;
+          }else if( (pTerm->eOperator & WO_IN)==0 ){
+            pIdxCons->usable = 1;
+          }
+          break;
+        case 1:    /* Constants with IN operators */
+          assert( seenIn );
+          pIdxCons->usable = (pTerm->prereqRight==0);
+          break;
+        case 2:    /* Variables without IN */
+          assert( seenVar );
+          pIdxCons->usable = (pTerm->eOperator & WO_IN)==0;
+          break;
+        default:   /* Variables with IN */
+          assert( seenVar && seenIn );
+          pIdxCons->usable = 1;
+          break;
+      }
+    }
+    memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
+    if( pIdxInfo->needToFreeIdxStr ) sqlite3_free(pIdxInfo->idxStr);
+    pIdxInfo->idxStr = 0;
+    pIdxInfo->idxNum = 0;
+    pIdxInfo->needToFreeIdxStr = 0;
+    pIdxInfo->orderByConsumed = 0;
+    pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
+    rc = vtabBestIndex(pParse, pTab, pIdxInfo);
+    if( rc ) goto whereLoopAddVtab_exit;
+    pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
+    pNew->prereq = 0;
+    mxTerm = -1;
+    assert( pNew->nLSlot>=nConstraint );
+    for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0;
+    pNew->u.vtab.omitMask = 0;
+    for(i=0; i<nConstraint; i++, pIdxCons++){
+      if( (iTerm = pUsage[i].argvIndex - 1)>=0 ){
+        j = pIdxCons->iTermOffset;
+        if( iTerm>=nConstraint
+         || j<0
+         || j>=pWC->nTerm
+         || pNew->aLTerm[iTerm]!=0
+        ){
+          rc = SQLITE_ERROR;
+          sqlite3ErrorMsg(pParse, "%s.xBestIndex() malfunction", pTab->zName);
+          goto whereLoopAddVtab_exit;
+        }
+        testcase( iTerm==nConstraint-1 );
+        testcase( j==0 );
+        testcase( j==pWC->nTerm-1 );
+        pTerm = &pWC->a[j];
+        pNew->prereq |= pTerm->prereqRight;
+        assert( iTerm<pNew->nLSlot );
+        pNew->aLTerm[iTerm] = pTerm;
+        if( iTerm>mxTerm ) mxTerm = iTerm;
+        testcase( iTerm==15 );
+        testcase( iTerm==16 );
+        if( iTerm<16 && pUsage[i].omit ) pNew->u.vtab.omitMask |= 1<<iTerm;
+        if( (pTerm->eOperator & WO_IN)!=0 ){
+          if( pUsage[i].omit==0 ){
+            /* Do not attempt to use an IN constraint if the virtual table
+            ** says that the equivalent EQ constraint cannot be safely omitted.
+            ** If we do attempt to use such a constraint, some rows might be
+            ** repeated in the output. */
+            break;
+          }
+          /* A virtual table that is constrained by an IN clause may not
+          ** consume the ORDER BY clause because (1) the order of IN terms
+          ** is not necessarily related to the order of output terms and
+          ** (2) Multiple outputs from a single IN value will not merge
+          ** together.  */
+          pIdxInfo->orderByConsumed = 0;
         }
       }
     }
-    whereClauseClear(pWInfo->pWC);
-    sqlite3DbFree(db, pWInfo);
+    if( i>=nConstraint ){
+      pNew->nLTerm = mxTerm+1;
+      assert( pNew->nLTerm<=pNew->nLSlot );
+      pNew->u.vtab.idxNum = pIdxInfo->idxNum;
+      pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr;
+      pIdxInfo->needToFreeIdxStr = 0;
+      pNew->u.vtab.idxStr = pIdxInfo->idxStr;
+      pNew->u.vtab.isOrdered = (u8)((pIdxInfo->nOrderBy!=0)
+                                     && pIdxInfo->orderByConsumed);
+      pNew->rSetup = 0;
+      pNew->rRun = whereCostFromDouble(pIdxInfo->estimatedCost);
+      /* TUNING: Every virtual table query returns 25 rows */
+      pNew->nOut = 46;  assert( 46==whereCost(25) );
+      whereLoopInsert(pBuilder, pNew);
+      if( pNew->u.vtab.needFree ){
+        sqlite3_free(pNew->u.vtab.idxStr);
+        pNew->u.vtab.needFree = 0;
+      }
+    }
+  }  
+
+whereLoopAddVtab_exit:
+  if( pIdxInfo->needToFreeIdxStr ) sqlite3_free(pIdxInfo->idxStr);
+  sqlite3DbFree(db, pIdxInfo);
+  return rc;
+}
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
+
+/*
+** Add WhereLoop entries to handle OR terms.  This works for either
+** btrees or virtual tables.
+*/
+static int whereLoopAddOr(WhereLoopBuilder *pBuilder, Bitmask mExtra){
+  WhereInfo *pWInfo = pBuilder->pWInfo;
+  WhereClause *pWC;
+  WhereLoop *pNew;
+  WhereTerm *pTerm, *pWCEnd;
+  int rc = SQLITE_OK;
+  int iCur;
+  WhereClause tempWC;
+  WhereLoopBuilder sSubBuild;
+  WhereOrSet sSum, sCur, sPrev;
+  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));
+
+  for(pTerm=pWC->a; pTerm<pWCEnd && rc==SQLITE_OK; pTerm++){
+    if( (pTerm->eOperator & WO_OR)!=0
+     && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0 
+    ){
+      WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc;
+      WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm];
+      WhereTerm *pOrTerm;
+      int once = 1;
+      int i, j;
+    
+      pItem = pWInfo->pTabList->a + pNew->iTab;
+      iCur = pItem->iCursor;
+      sSubBuild = *pBuilder;
+      sSubBuild.pOrderBy = 0;
+      sSubBuild.pOrSet = &sCur;
+
+      for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
+        if( (pOrTerm->eOperator & WO_AND)!=0 ){
+          sSubBuild.pWC = &pOrTerm->u.pAndInfo->wc;
+        }else if( pOrTerm->leftCursor==iCur ){
+          tempWC.pWInfo = pWC->pWInfo;
+          tempWC.pOuter = pWC;
+          tempWC.op = TK_AND;
+          tempWC.nTerm = 1;
+          tempWC.a = pOrTerm;
+          sSubBuild.pWC = &tempWC;
+        }else{
+          continue;
+        }
+        sCur.n = 0;
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+        if( IsVirtual(pItem->pTab) ){
+          rc = whereLoopAddVirtual(&sSubBuild);
+          for(i=0; i<sCur.n; i++) sCur.a[i].prereq |= mExtra;
+        }else
+#endif
+        {
+          rc = whereLoopAddBtree(&sSubBuild, mExtra);
+        }
+        assert( rc==SQLITE_OK || sCur.n==0 );
+        if( sCur.n==0 ){
+          sSum.n = 0;
+          break;
+        }else if( once ){
+          whereOrMove(&sSum, &sCur);
+          once = 0;
+        }else{
+          whereOrMove(&sPrev, &sSum);
+          sSum.n = 0;
+          for(i=0; i<sPrev.n; i++){
+            for(j=0; j<sCur.n; j++){
+              whereOrInsert(&sSum, sPrev.a[i].prereq | sCur.a[j].prereq,
+                            whereCostAdd(sPrev.a[i].rRun, sCur.a[j].rRun),
+                            whereCostAdd(sPrev.a[i].nOut, sCur.a[j].nOut));
+            }
+          }
+        }
+      }
+      pNew->nLTerm = 1;
+      pNew->aLTerm[0] = pTerm;
+      pNew->wsFlags = WHERE_MULTI_OR;
+      pNew->rSetup = 0;
+      pNew->iSortIdx = 0;
+      memset(&pNew->u, 0, sizeof(pNew->u));
+      for(i=0; rc==SQLITE_OK && i<sSum.n; i++){
+        /* TUNING: Multiple by 3.5 for the secondary table lookup */
+        pNew->rRun = sSum.a[i].rRun + 18;
+        pNew->nOut = sSum.a[i].nOut;
+        pNew->prereq = sSum.a[i].prereq;
+        rc = whereLoopInsert(pBuilder, pNew);
+      }
+    }
+  }
+  return rc;
+}
+
+/*
+** Add all WhereLoop objects for all tables 
+*/
+static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
+  WhereInfo *pWInfo = pBuilder->pWInfo;
+  Bitmask mExtra = 0;
+  Bitmask mPrior = 0;
+  int iTab;
+  SrcList *pTabList = pWInfo->pTabList;
+  struct SrcList_item *pItem;
+  sqlite3 *db = pWInfo->pParse->db;
+  int nTabList = pWInfo->nLevel;
+  int rc = SQLITE_OK;
+  u8 priorJoinType = 0;
+  WhereLoop *pNew;
+
+  /* Loop over the tables in the join, from left to right */
+  pNew = pBuilder->pNew;
+  whereLoopInit(pNew);
+  for(iTab=0, pItem=pTabList->a; iTab<nTabList; iTab++, pItem++){
+    pNew->iTab = iTab;
+    pNew->maskSelf = getMask(&pWInfo->sMaskSet, pItem->iCursor);
+    if( ((pItem->jointype|priorJoinType) & (JT_LEFT|JT_CROSS))!=0 ){
+      mExtra = mPrior;
+    }
+    priorJoinType = pItem->jointype;
+    if( IsVirtual(pItem->pTab) ){
+      rc = whereLoopAddVirtual(pBuilder);
+    }else{
+      rc = whereLoopAddBtree(pBuilder, mExtra);
+    }
+    if( rc==SQLITE_OK ){
+      rc = whereLoopAddOr(pBuilder, mExtra);
+    }
+    mPrior |= pNew->maskSelf;
+    if( rc || db->mallocFailed ) break;
+  }
+  whereLoopClear(db, pNew);
+  return rc;
+}
+
+/*
+** Examine a WherePath (with the addition of the extra WhereLoop of the 5th
+** parameters) to see if it outputs rows in the requested ORDER BY
+** (or GROUP BY) without requiring a separate sort operation.  Return:
+** 
+**    0:  ORDER BY is not satisfied.  Sorting required
+**    1:  ORDER BY is satisfied.      Omit sorting
+**   -1:  Unknown at this time
+**
+** Note that processing for WHERE_GROUPBY and WHERE_DISTINCTBY is not as
+** strict.  With GROUP BY and DISTINCT the only requirement is that
+** equivalent rows appear immediately adjacent to one another.  GROUP BY
+** and DISTINT do not require rows to appear in any particular order as long
+** as equivelent 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.
+*/
+static int wherePathSatisfiesOrderBy(
+  WhereInfo *pWInfo,    /* The WHERE clause */
+  ExprList *pOrderBy,   /* ORDER BY or GROUP BY or DISTINCT clause to check */
+  WherePath *pPath,     /* The WherePath to check */
+  u16 wctrlFlags,       /* Might contain WHERE_GROUPBY or WHERE_DISTINCTBY */
+  u16 nLoop,            /* Number of entries in pPath->aLoop[] */
+  WhereLoop *pLast,     /* Add this WhereLoop to the end of pPath->aLoop[] */
+  Bitmask *pRevMask     /* OUT: Mask of WhereLoops to run in reverse order */
+){
+  u8 revSet;            /* True if rev is known */
+  u8 rev;               /* Composite sort order */
+  u8 revIdx;            /* Index sort order */
+  u8 isOrderDistinct;   /* All prior WhereLoops are order-distinct */
+  u8 distinctColumns;   /* True if the loop has UNIQUE NOT NULL columns */
+  u8 isMatch;           /* iColumn matches a term of the ORDER BY clause */
+  u16 nColumn;          /* Number of columns in pIndex */
+  u16 nOrderBy;         /* Number terms in the ORDER BY clause */
+  int iLoop;            /* Index of WhereLoop in pPath being processed */
+  int i, j;             /* Loop counters */
+  int iCur;             /* Cursor number for current WhereLoop */
+  int iColumn;          /* A column number within table iCur */
+  WhereLoop *pLoop = 0; /* Current WhereLoop being processed. */
+  WhereTerm *pTerm;     /* A single term of the WHERE clause */
+  Expr *pOBExpr;        /* An expression from the ORDER BY clause */
+  CollSeq *pColl;       /* COLLATE function from an ORDER BY clause term */
+  Index *pIndex;        /* The index associated with pLoop */
+  sqlite3 *db = pWInfo->pParse->db;  /* Database connection */
+  Bitmask obSat = 0;    /* Mask of ORDER BY terms satisfied so far */
+  Bitmask obDone;       /* Mask of all ORDER BY terms */
+  Bitmask orderDistinctMask;  /* Mask of all well-ordered loops */
+  Bitmask ready;              /* Mask of inner loops */
+
+  /*
+  ** We say the WhereLoop is "one-row" if it generates no more than one
+  ** row of output.  A WhereLoop is one-row if all of the following are true:
+  **  (a) All index columns match with WHERE_COLUMN_EQ.
+  **  (b) The index is unique
+  ** Any WhereLoop with an WHERE_COLUMN_EQ constraint on the rowid is one-row.
+  ** Every one-row WhereLoop will have the WHERE_ONEROW bit set in wsFlags.
+  **
+  ** We say the WhereLoop is "order-distinct" if the set of columns from
+  ** that WhereLoop that are in the ORDER BY clause are different for every
+  ** row of the WhereLoop.  Every one-row WhereLoop is automatically
+  ** order-distinct.   A WhereLoop that has no columns in the ORDER BY clause
+  ** is not order-distinct. To be order-distinct is not quite the same as being
+  ** UNIQUE since a UNIQUE column or index can have multiple rows that 
+  ** are NULL and NULL values are equivalent for the purpose of order-distinct.
+  ** To be order-distinct, the columns must be UNIQUE and NOT NULL.
+  **
+  ** The rowid for a table is always UNIQUE and NOT NULL so whenever the
+  ** rowid appears in the ORDER BY clause, the corresponding WhereLoop is
+  ** automatically order-distinct.
+  */
+
+  assert( pOrderBy!=0 );
+
+  /* Sortability of virtual tables is determined by the xBestIndex method
+  ** of the virtual table itself */
+  if( pLast->wsFlags & WHERE_VIRTUALTABLE ){
+    testcase( nLoop>0 );  /* True when outer loops are one-row and match 
+                          ** no ORDER BY terms */
+    return pLast->u.vtab.isOrdered;
+  }
+  if( nLoop && OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ) return 0;
+
+  nOrderBy = pOrderBy->nExpr;
+  testcase( nOrderBy==BMS-1 );
+  if( nOrderBy>BMS-1 ) return 0;  /* Cannot optimize overly large ORDER BYs */
+  isOrderDistinct = 1;
+  obDone = MASKBIT(nOrderBy)-1;
+  orderDistinctMask = 0;
+  ready = 0;
+  for(iLoop=0; isOrderDistinct && obSat<obDone && iLoop<=nLoop; iLoop++){
+    if( iLoop>0 ) ready |= pLoop->maskSelf;
+    pLoop = iLoop<nLoop ? pPath->aLoop[iLoop] : pLast;
+    assert( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 );
+    iCur = pWInfo->pTabList->a[pLoop->iTab].iCursor;
+
+    /* Mark off any ORDER BY term X that is a column in the table of
+    ** the current loop for which there is term in the WHERE
+    ** clause of the form X IS NULL or X=? that reference only outer
+    ** loops.
+    */
+    for(i=0; i<nOrderBy; i++){
+      if( MASKBIT(i) & obSat ) continue;
+      pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[i].pExpr);
+      if( pOBExpr->op!=TK_COLUMN ) continue;
+      if( pOBExpr->iTable!=iCur ) continue;
+      pTerm = findTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn,
+                       ~ready, WO_EQ|WO_ISNULL, 0);
+      if( pTerm==0 ) continue;
+      if( (pTerm->eOperator&WO_EQ)!=0 && pOBExpr->iColumn>=0 ){
+        const char *z1, *z2;
+        pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
+        if( !pColl ) pColl = db->pDfltColl;
+        z1 = pColl->zName;
+        pColl = sqlite3ExprCollSeq(pWInfo->pParse, pTerm->pExpr);
+        if( !pColl ) pColl = db->pDfltColl;
+        z2 = pColl->zName;
+        if( sqlite3StrICmp(z1, z2)!=0 ) continue;
+      }
+      obSat |= MASKBIT(i);
+    }
+
+    if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){
+      if( pLoop->wsFlags & WHERE_IPK ){
+        pIndex = 0;
+        nColumn = 0;
+      }else if( (pIndex = pLoop->u.btree.pIndex)==0 || pIndex->bUnordered ){
+        return 0;
+      }else{
+        nColumn = pIndex->nColumn;
+        isOrderDistinct = pIndex->onError!=OE_None;
+      }
+
+      /* Loop through all columns of the index and deal with the ones
+      ** that are not constrained by == or IN.
+      */
+      rev = revSet = 0;
+      distinctColumns = 0;
+      for(j=0; j<=nColumn; j++){
+        u8 bOnce;   /* True to run the ORDER BY search loop */
+
+        /* Skip over == and IS NULL terms */
+        if( j<pLoop->u.btree.nEq
+         && ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL))!=0
+        ){
+          if( i & WO_ISNULL ){
+            testcase( isOrderDistinct );
+            isOrderDistinct = 0;
+          }
+          continue;  
+        }
+
+        /* Get the column number in the table (iColumn) and sort order
+        ** (revIdx) for the j-th column of the index.
+        */
+        if( j<nColumn ){
+          /* Normal index columns */
+          iColumn = pIndex->aiColumn[j];
+          revIdx = pIndex->aSortOrder[j];
+          if( iColumn==pIndex->pTable->iPKey ) iColumn = -1;
+        }else{
+          /* The ROWID column at the end */
+          assert( j==nColumn );
+          iColumn = -1;
+          revIdx = 0;
+        }
+
+        /* An unconstrained column that might be NULL means that this
+        ** WhereLoop is not well-ordered 
+        */
+        if( isOrderDistinct
+         && iColumn>=0
+         && j>=pLoop->u.btree.nEq
+         && pIndex->pTable->aCol[iColumn].notNull==0
+        ){
+          isOrderDistinct = 0;
+        }
+
+        /* Find the ORDER BY term that corresponds to the j-th column
+        ** of the index and and mark that ORDER BY term off 
+        */
+        bOnce = 1;
+        isMatch = 0;
+        for(i=0; bOnce && i<nOrderBy; i++){
+          if( MASKBIT(i) & obSat ) continue;
+          pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[i].pExpr);
+          testcase( wctrlFlags & WHERE_GROUPBY );
+          testcase( wctrlFlags & WHERE_DISTINCTBY );
+          if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0;
+          if( pOBExpr->op!=TK_COLUMN ) continue;
+          if( pOBExpr->iTable!=iCur ) continue;
+          if( pOBExpr->iColumn!=iColumn ) continue;
+          if( iColumn>=0 ){
+            pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
+            if( !pColl ) pColl = db->pDfltColl;
+            if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue;
+          }
+          isMatch = 1;
+          break;
+        }
+        if( isMatch ){
+          if( iColumn<0 ){
+            testcase( distinctColumns==0 );
+            distinctColumns = 1;
+          }
+          obSat |= MASKBIT(i);
+          if( (pWInfo->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 ){
+              if( (rev ^ revIdx)!=pOrderBy->a[i].sortOrder ) return 0;
+            }else{
+              rev = revIdx ^ pOrderBy->a[i].sortOrder;
+              if( rev ) *pRevMask |= MASKBIT(iLoop);
+              revSet = 1;
+            }
+          }
+        }else{
+          /* No match found */
+          if( j==0 || j<nColumn ){
+            testcase( isOrderDistinct!=0 );
+            isOrderDistinct = 0;
+          }
+          break;
+        }
+      } /* end Loop over all index columns */
+      if( distinctColumns ){
+        testcase( isOrderDistinct==0 );
+        isOrderDistinct = 1;
+      }
+    } /* end-if not one-row */
+
+    /* Mark off any other ORDER BY terms that reference pLoop */
+    if( isOrderDistinct ){
+      orderDistinctMask |= pLoop->maskSelf;
+      for(i=0; i<nOrderBy; i++){
+        Expr *p;
+        if( MASKBIT(i) & obSat ) continue;
+        p = pOrderBy->a[i].pExpr;
+        if( (exprTableUsage(&pWInfo->sMaskSet, p)&~orderDistinctMask)==0 ){
+          obSat |= MASKBIT(i);
+        }
+      }
+    }
+  } /* End the loop over all WhereLoops from outer-most down to inner-most */
+  if( obSat==obDone ) return 1;
+  if( !isOrderDistinct ) return 0;
+  return -1;
+}
+
+#ifdef WHERETRACE_ENABLED
+/* For debugging use only: */
+static const char *wherePathName(WherePath *pPath, int nLoop, WhereLoop *pLast){
+  static char zName[65];
+  int i;
+  for(i=0; i<nLoop; i++){ zName[i] = pPath->aLoop[i]->cId; }
+  if( pLast ) zName[i++] = pLast->cId;
+  zName[i] = 0;
+  return zName;
+}
+#endif
+
+
+/*
+** Given the list of WhereLoop objects at pWInfo->pLoops, this routine
+** attempts to find the lowest cost path that visits each WhereLoop
+** once.  This path is then loaded into the pWInfo->a[].pWLoop fields.
+**
+** Assume that the total number of output rows that will need to be sorted
+** will be nRowEst (in the 10*log2 representation).  Or, ignore sorting
+** costs if nRowEst==0.
+**
+** Return SQLITE_OK on success or SQLITE_NOMEM of a memory allocation
+** error occurs.
+*/
+static int wherePathSolver(WhereInfo *pWInfo, WhereCost nRowEst){
+  int mxChoice;             /* Maximum number of simultaneous paths tracked */
+  int nLoop;                /* Number of terms in the join */
+  Parse *pParse;            /* Parsing context */
+  sqlite3 *db;              /* The database connection */
+  int iLoop;                /* Loop counter over the terms of the join */
+  int ii, jj;               /* Loop counters */
+  WhereCost rCost;             /* Cost of a path */
+  WhereCost mxCost = 0;        /* Maximum cost of a set of paths */
+  WhereCost rSortCost;         /* Cost to do a sort */
+  int nTo, nFrom;           /* Number of valid entries in aTo[] and aFrom[] */
+  WherePath *aFrom;         /* All nFrom paths at the previous level */
+  WherePath *aTo;           /* The nTo best paths at the current level */
+  WherePath *pFrom;         /* An element of aFrom[] that we are working on */
+  WherePath *pTo;           /* An element of aTo[] that we are working on */
+  WhereLoop *pWLoop;        /* One of the WhereLoop objects */
+  WhereLoop **pX;           /* Used to divy up the pSpace memory */
+  char *pSpace;             /* Temporary memory used by this routine */
+
+  pParse = pWInfo->pParse;
+  db = pParse->db;
+  nLoop = pWInfo->nLevel;
+  /* TUNING: For simple queries, only the best path is tracked.
+  ** For 2-way joins, the 5 best paths are followed.
+  ** For joins of 3 or more tables, track the 10 best paths */
+  mxChoice = (nLoop==1) ? 1 : (nLoop==2 ? 5 : 10);
+  assert( nLoop<=pWInfo->pTabList->nSrc );
+  WHERETRACE(0x002, ("---- begin solver\n"));
+
+  /* Allocate and initialize space for aTo and aFrom */
+  ii = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2;
+  pSpace = sqlite3DbMallocRaw(db, ii);
+  if( pSpace==0 ) return SQLITE_NOMEM;
+  aTo = (WherePath*)pSpace;
+  aFrom = aTo+mxChoice;
+  memset(aFrom, 0, sizeof(aFrom[0]));
+  pX = (WhereLoop**)(aFrom+mxChoice);
+  for(ii=mxChoice*2, pFrom=aTo; ii>0; ii--, pFrom++, pX += nLoop){
+    pFrom->aLoop = pX;
+  }
+
+  /* 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
+  ** rows, then do not use the automatic index. */
+  aFrom[0].nRow = MIN(pParse->nQueryLoop, 46);  assert( 46==whereCost(25) );
+  nFrom = 1;
+
+  /* Precompute the cost of sorting the final result set, if the caller
+  ** to sqlite3WhereBegin() was concerned about sorting */
+  rSortCost = 0;
+  if( pWInfo->pOrderBy==0 || nRowEst==0 ){
+    aFrom[0].isOrderedValid = 1;
+  }else{
+    /* TUNING: Estimated cost of sorting is N*log2(N) where N is the
+    ** number of output rows. */
+    rSortCost = nRowEst + estLog(nRowEst);
+    WHERETRACE(0x002,("---- sort cost=%-3d\n", rSortCost));
+  }
+
+  /* Compute successively longer WherePaths using the previous generation
+  ** of WherePaths as the basis for the next.  Keep track of the mxChoice
+  ** best paths at each generation */
+  for(iLoop=0; iLoop<nLoop; iLoop++){
+    nTo = 0;
+    for(ii=0, pFrom=aFrom; ii<nFrom; ii++, pFrom++){
+      for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){
+        Bitmask maskNew;
+        Bitmask revMask = 0;
+        u8 isOrderedValid = pFrom->isOrderedValid;
+        u8 isOrdered = pFrom->isOrdered;
+        if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue;
+        if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue;
+        /* At this point, pWLoop is a candidate to be the next loop. 
+        ** Compute its cost */
+        rCost = whereCostAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow);
+        rCost = whereCostAdd(rCost, pFrom->rCost);
+        maskNew = pFrom->maskLoop | pWLoop->maskSelf;
+        if( !isOrderedValid ){
+          switch( wherePathSatisfiesOrderBy(pWInfo,
+                       pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags,
+                       iLoop, pWLoop, &revMask) ){
+            case 1:  /* Yes.  pFrom+pWLoop does satisfy the ORDER BY clause */
+              isOrdered = 1;
+              isOrderedValid = 1;
+              break;
+            case 0:  /* No.  pFrom+pWLoop will require a separate sort */
+              isOrdered = 0;
+              isOrderedValid = 1;
+              rCost = whereCostAdd(rCost, rSortCost);
+              break;
+            default: /* Cannot tell yet.  Try again on the next iteration */
+              break;
+          }
+        }else{
+          revMask = pFrom->revLoop;
+        }
+        /* Check to see if pWLoop should be added to the mxChoice best so far */
+        for(jj=0, pTo=aTo; jj<nTo; jj++, pTo++){
+          if( pTo->maskLoop==maskNew && pTo->isOrderedValid==isOrderedValid ){
+            testcase( jj==nTo-1 );
+            break;
+          }
+        }
+        if( jj>=nTo ){
+          if( nTo>=mxChoice && rCost>=mxCost ){
+#ifdef WHERETRACE_ENABLED
+            if( sqlite3WhereTrace&0x4 ){
+              sqlite3DebugPrintf("Skip   %s cost=%3d order=%c\n",
+                  wherePathName(pFrom, iLoop, pWLoop), rCost,
+                  isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?');
+            }
+#endif
+            continue;
+          }
+          /* Add a new Path to the aTo[] set */
+          if( nTo<mxChoice ){
+            /* Increase the size of the aTo set by one */
+            jj = nTo++;
+          }else{
+            /* New path replaces the prior worst to keep count below mxChoice */
+            for(jj=nTo-1; aTo[jj].rCost<mxCost; jj--){ assert(jj>0); }
+          }
+          pTo = &aTo[jj];
+#ifdef WHERETRACE_ENABLED
+          if( sqlite3WhereTrace&0x4 ){
+            sqlite3DebugPrintf("New    %s cost=%-3d order=%c\n",
+                wherePathName(pFrom, iLoop, pWLoop), rCost,
+                isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?');
+          }
+#endif
+        }else{
+          if( pTo->rCost<=rCost ){
+#ifdef WHERETRACE_ENABLED
+            if( sqlite3WhereTrace&0x4 ){
+              sqlite3DebugPrintf(
+                  "Skip   %s cost=%-3d order=%c",
+                  wherePathName(pFrom, iLoop, pWLoop), rCost,
+                  isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?');
+              sqlite3DebugPrintf("   vs %s cost=%-3d order=%c\n",
+                  wherePathName(pTo, iLoop+1, 0), pTo->rCost,
+                  pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?');
+            }
+#endif
+            testcase( pTo->rCost==rCost );
+            continue;
+          }
+          testcase( pTo->rCost==rCost+1 );
+          /* A new and better score for a previously created equivalent path */
+#ifdef WHERETRACE_ENABLED
+          if( sqlite3WhereTrace&0x4 ){
+            sqlite3DebugPrintf(
+                "Update %s cost=%-3d order=%c",
+                wherePathName(pFrom, iLoop, pWLoop), rCost,
+                isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?');
+            sqlite3DebugPrintf("  was %s cost=%-3d order=%c\n",
+                wherePathName(pTo, iLoop+1, 0), pTo->rCost,
+                pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?');
+          }
+#endif
+        }
+        /* pWLoop is a winner.  Add it to the set of best so far */
+        pTo->maskLoop = pFrom->maskLoop | pWLoop->maskSelf;
+        pTo->revLoop = revMask;
+        pTo->nRow = pFrom->nRow + pWLoop->nOut;
+        pTo->rCost = rCost;
+        pTo->isOrderedValid = isOrderedValid;
+        pTo->isOrdered = isOrdered;
+        memcpy(pTo->aLoop, pFrom->aLoop, sizeof(WhereLoop*)*iLoop);
+        pTo->aLoop[iLoop] = pWLoop;
+        if( nTo>=mxChoice ){
+          mxCost = aTo[0].rCost;
+          for(jj=1, pTo=&aTo[1]; jj<mxChoice; jj++, pTo++){
+            if( pTo->rCost>mxCost ) mxCost = pTo->rCost;
+          }
+        }
+      }
+    }
+
+#ifdef WHERETRACE_ENABLED
+    if( sqlite3WhereTrace>=2 ){
+      sqlite3DebugPrintf("---- after round %d ----\n", iLoop);
+      for(ii=0, pTo=aTo; ii<nTo; ii++, pTo++){
+        sqlite3DebugPrintf(" %s cost=%-3d nrow=%-3d order=%c",
+           wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow,
+           pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?');
+        if( pTo->isOrderedValid && pTo->isOrdered ){
+          sqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop);
+        }else{
+          sqlite3DebugPrintf("\n");
+        }
+      }
+    }
+#endif
+
+    /* Swap the roles of aFrom and aTo for the next generation */
+    pFrom = aTo;
+    aTo = aFrom;
+    aFrom = pFrom;
+    nFrom = nTo;
   }
+
+  if( nFrom==0 ){
+    sqlite3ErrorMsg(pParse, "no query solution");
+    sqlite3DbFree(db, pSpace);
+    return SQLITE_ERROR;
+  }
+  
+  /* Find the lowest cost path.  pFrom will be left pointing to that path */
+  pFrom = aFrom;
+  assert( nFrom==1 );
+#if 0 /* The following is needed if nFrom is ever more than 1 */
+  for(ii=1; ii<nFrom; ii++){
+    if( pFrom->rCost>aFrom[ii].rCost ) pFrom = &aFrom[ii];
+  }
+#endif
+  assert( pWInfo->nLevel==nLoop );
+  /* Load the lowest cost path into pWInfo */
+  for(iLoop=0; iLoop<nLoop; iLoop++){
+    WhereLevel *pLevel = pWInfo->a + iLoop;
+    pLevel->pWLoop = pWLoop = pFrom->aLoop[iLoop];
+    pLevel->iFrom = pWLoop->iTab;
+    pLevel->iTabCur = pWInfo->pTabList->a[pLevel->iFrom].iCursor;
+  }
+  if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)!=0
+   && (pWInfo->wctrlFlags & WHERE_DISTINCTBY)==0
+   && pWInfo->eDistinct==WHERE_DISTINCT_NOOP
+   && nRowEst
+  ){
+    Bitmask notUsed;
+    int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pResultSet, pFrom,
+                 WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], &notUsed);
+    if( rc==1 ) pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
+  }
+  if( pFrom->isOrdered ){
+    if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){
+      pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
+    }else{
+      pWInfo->bOBSat = 1;
+      pWInfo->revMask = pFrom->revLoop;
+    }
+  }
+  pWInfo->nRowOut = pFrom->nRow;
+
+  /* Free temporary memory and return success */
+  sqlite3DbFree(db, pSpace);
+  return SQLITE_OK;
 }
 
+/*
+** Most queries use only a single table (they are not joins) and have
+** simple == constraints against indexed fields.  This routine attempts
+** to plan those simple cases using much less ceremony than the
+** general-purpose query planner, and thereby yield faster sqlite3_prepare()
+** times for the common case.
+**
+** Return non-zero on success, if this query can be handled by this
+** no-frills query planner.  Return zero if this query needs the 
+** general-purpose query planner.
+*/
+static int whereShortCut(WhereLoopBuilder *pBuilder){
+  WhereInfo *pWInfo;
+  struct SrcList_item *pItem;
+  WhereClause *pWC;
+  WhereTerm *pTerm;
+  WhereLoop *pLoop;
+  int iCur;
+  int j;
+  Table *pTab;
+  Index *pIdx;
+  
+  pWInfo = pBuilder->pWInfo;
+  if( pWInfo->wctrlFlags & WHERE_FORCE_TABLE ) return 0;
+  assert( pWInfo->pTabList->nSrc>=1 );
+  pItem = pWInfo->pTabList->a;
+  pTab = pItem->pTab;
+  if( IsVirtual(pTab) ) return 0;
+  if( pItem->zIndex ) return 0;
+  iCur = pItem->iCursor;
+  pWC = &pWInfo->sWC;
+  pLoop = pBuilder->pNew;
+  pLoop->wsFlags = 0;
+  pTerm = findTerm(pWC, iCur, -1, 0, WO_EQ, 0);
+  if( pTerm ){
+    pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW;
+    pLoop->aLTerm[0] = pTerm;
+    pLoop->nLTerm = 1;
+    pLoop->u.btree.nEq = 1;
+    /* TUNING: Cost of a rowid lookup is 10 */
+    pLoop->rRun = 33;  /* 33==whereCost(10) */
+  }else{
+    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+      assert( pLoop->aLTermSpace==pLoop->aLTerm );
+      assert( ArraySize(pLoop->aLTermSpace)==4 );
+      if( pIdx->onError==OE_None 
+       || pIdx->pPartIdxWhere!=0 
+       || pIdx->nColumn>ArraySize(pLoop->aLTermSpace) 
+      ) continue;
+      for(j=0; j<pIdx->nColumn; j++){
+        pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, WO_EQ, pIdx);
+        if( pTerm==0 ) break;
+        pLoop->aLTerm[j] = pTerm;
+      }
+      if( j!=pIdx->nColumn ) continue;
+      pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED;
+      if( (pItem->colUsed & ~columnsInIndex(pIdx))==0 ){
+        pLoop->wsFlags |= WHERE_IDX_ONLY;
+      }
+      pLoop->nLTerm = j;
+      pLoop->u.btree.nEq = j;
+      pLoop->u.btree.pIndex = pIdx;
+      /* TUNING: Cost of a unique index lookup is 15 */
+      pLoop->rRun = 39;  /* 39==whereCost(15) */
+      break;
+    }
+  }
+  if( pLoop->wsFlags ){
+    pLoop->nOut = (WhereCost)1;
+    pWInfo->a[0].pWLoop = pLoop;
+    pLoop->maskSelf = getMask(&pWInfo->sMaskSet, iCur);
+    pWInfo->a[0].iTabCur = iCur;
+    pWInfo->nRowOut = 1;
+    if( pWInfo->pOrderBy ) pWInfo->bOBSat =  1;
+    if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){
+      pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
+    }
+#ifdef SQLITE_DEBUG
+    pLoop->cId = '0';
+#endif
+    return 1;
+  }
+  return 0;
+}
 
 /*
 ** Generate the beginning of the loop used for WHERE clause processing.
@@ -109463,25 +110476,17 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
 **
 ** ORDER BY CLAUSE PROCESSING
 **
-** pOrderBy is a pointer to the ORDER BY clause of a SELECT statement,
+** pOrderBy is a pointer to the ORDER BY clause (or the GROUP BY clause
+** if the WHERE_GROUPBY flag is set in wctrlFlags) of a SELECT statement
 ** if there is one.  If there is no ORDER BY clause or if this routine
 ** is called from an UPDATE or DELETE statement, then pOrderBy is NULL.
-**
-** If an index can be used so that the natural output order of the table
-** scan is correct for the ORDER BY clause, then that index is used and
-** the returned WhereInfo.nOBSat field is set to pOrderBy->nExpr.  This
-** is an optimization that prevents an unnecessary sort of the result set
-** if an index appropriate for the ORDER BY clause already exists.
-**
-** If the where clause loops cannot be arranged to provide the correct
-** output order, then WhereInfo.nOBSat is 0.
 */
 SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
   Parse *pParse,        /* The parser context */
-  SrcList *pTabList,    /* A list of all tables to be scanned */
+  SrcList *pTabList,    /* FROM clause: A list of all tables to be scanned */
   Expr *pWhere,         /* The WHERE clause */
   ExprList *pOrderBy,   /* An ORDER BY clause, or NULL */
-  ExprList *pDistinct,  /* The select-list for DISTINCT queries - or NULL */
+  ExprList *pResultSet, /* Result set of the query */
   u16 wctrlFlags,       /* One of the WHERE_* flags defined in sqliteInt.h */
   int iIdxCur           /* If WHERE_ONETABLE_ONLY is set, index cursor number */
 ){
@@ -109490,18 +110495,25 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
   WhereInfo *pWInfo;         /* Will become the return value of this function */
   Vdbe *v = pParse->pVdbe;   /* The virtual database engine */
   Bitmask notReady;          /* Cursors that are not yet positioned */
-  WhereBestIdx sWBI;         /* Best index search context */
+  WhereLoopBuilder sWLB;     /* The WhereLoop builder */
   WhereMaskSet *pMaskSet;    /* The expression mask set */
   WhereLevel *pLevel;        /* A single level in pWInfo->a[] */
-  int iFrom;                 /* First unused FROM clause element */
-  int andFlags;              /* AND-ed combination of all pWC->a[].wtFlags */
+  WhereLoop *pLoop;          /* Pointer to a single WhereLoop object */
   int ii;                    /* Loop counter */
   sqlite3 *db;               /* Database connection */
+  int rc;                    /* Return code */
 
 
   /* Variable initialization */
-  memset(&sWBI, 0, sizeof(sWBI));
-  sWBI.pParse = pParse;
+  db = pParse->db;
+  memset(&sWLB, 0, sizeof(sWLB));
+  sWLB.pOrderBy = pOrderBy;
+
+  /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via
+  ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */
+  if( OptimizationDisabled(db, SQLITE_DistinctOpt) ){
+    wctrlFlags &= ~WHERE_WANT_DISTINCT;
+  }
 
   /* The number of tables in the FROM clause is limited by the number of
   ** bits in a Bitmask 
@@ -109526,13 +110538,8 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
   ** field (type Bitmask) it must be aligned on an 8-byte boundary on
   ** some architectures. Hence the ROUND8() below.
   */
-  db = pParse->db;
   nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel));
-  pWInfo = sqlite3DbMallocZero(db, 
-      nByteWInfo + 
-      sizeof(WhereClause) +
-      sizeof(WhereMaskSet)
-  );
+  pWInfo = sqlite3DbMallocZero(db, nByteWInfo + sizeof(WhereLoop));
   if( db->mallocFailed ){
     sqlite3DbFree(db, pWInfo);
     pWInfo = 0;
@@ -109541,24 +110548,29 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
   pWInfo->nLevel = nTabList;
   pWInfo->pParse = pParse;
   pWInfo->pTabList = pTabList;
+  pWInfo->pOrderBy = pOrderBy;
+  pWInfo->pResultSet = pResultSet;
   pWInfo->iBreak = sqlite3VdbeMakeLabel(v);
-  pWInfo->pWC = sWBI.pWC = (WhereClause *)&((u8 *)pWInfo)[nByteWInfo];
   pWInfo->wctrlFlags = wctrlFlags;
   pWInfo->savedNQueryLoop = pParse->nQueryLoop;
-  pMaskSet = (WhereMaskSet*)&sWBI.pWC[1];
-  sWBI.aLevel = pWInfo->a;
-
-  /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via
-  ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */
-  if( OptimizationDisabled(db, SQLITE_DistinctOpt) ) pDistinct = 0;
+  pMaskSet = &pWInfo->sMaskSet;
+  sWLB.pWInfo = pWInfo;
+  sWLB.pWC = &pWInfo->sWC;
+  sWLB.pNew = (WhereLoop*)(((char*)pWInfo)+nByteWInfo);
+  assert( EIGHT_BYTE_ALIGNMENT(sWLB.pNew) );
+  whereLoopInit(sWLB.pNew);
+#ifdef SQLITE_DEBUG
+  sWLB.pNew->cId = '*';
+#endif
 
   /* Split the WHERE clause into separate subexpressions where each
   ** subexpression is separated by an AND operator.
   */
   initMaskSet(pMaskSet);
-  whereClauseInit(sWBI.pWC, pParse, pMaskSet, wctrlFlags);
+  whereClauseInit(&pWInfo->sWC, pWInfo);
   sqlite3ExprCodeConstants(pParse, pWhere);
-  whereSplit(sWBI.pWC, pWhere, TK_AND);   /* IMP: R-15842-53296 */
+  whereSplit(&pWInfo->sWC, pWhere, TK_AND);
+  sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
     
   /* Special case: a WHERE clause that is constant.  Evaluate the
   ** expression and either jump over all of the code or fall thru.
@@ -109568,6 +110580,15 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
     pWhere = 0;
   }
 
+  /* Special case: No FROM clause
+  */
+  if( nTabList==0 ){
+    if( pOrderBy ) pWInfo->bOBSat = 1;
+    if( wctrlFlags & WHERE_WANT_DISTINCT ){
+      pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
+    }
+  }
+
   /* Assign a bit from the bitmask to every term in the FROM clause.
   **
   ** When assigning bitmask values to FROM clause cursors, it must be
@@ -109603,288 +110624,131 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
   ** want to analyze these virtual terms, so start analyzing at the end
   ** and work forward so that the added virtual terms are never processed.
   */
-  exprAnalyzeAll(pTabList, sWBI.pWC);
+  exprAnalyzeAll(pTabList, &pWInfo->sWC);
   if( db->mallocFailed ){
     goto whereBeginError;
   }
 
-  /* Check if the DISTINCT qualifier, if there is one, is redundant. 
-  ** If it is, then set pDistinct to NULL and WhereInfo.eDistinct to
-  ** WHERE_DISTINCT_UNIQUE to tell the caller to ignore the DISTINCT.
+  /* If the ORDER BY (or GROUP BY) clause contains references to general
+  ** expressions, then we won't be able to satisfy it using indices, so
+  ** go ahead and disable it now.
   */
-  if( pDistinct && isDistinctRedundant(pParse, pTabList, sWBI.pWC, pDistinct) ){
-    pDistinct = 0;
-    pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
+  if( pOrderBy && (wctrlFlags & WHERE_WANT_DISTINCT)!=0 ){
+    for(ii=0; ii<pOrderBy->nExpr; ii++){
+      Expr *pExpr = sqlite3ExprSkipCollate(pOrderBy->a[ii].pExpr);
+      if( pExpr->op!=TK_COLUMN ){
+        pWInfo->pOrderBy = pOrderBy = 0;
+        break;
+      }else if( pExpr->iColumn<0 ){
+        break;
+      }
+    }
   }
 
-  /* Chose the best index to use for each table in the FROM clause.
-  **
-  ** This loop fills in the following fields:
-  **
-  **   pWInfo->a[].pIdx      The index to use for this level of the loop.
-  **   pWInfo->a[].wsFlags   WHERE_xxx flags associated with pIdx
-  **   pWInfo->a[].nEq       The number of == and IN constraints
-  **   pWInfo->a[].iFrom     Which term of the FROM clause is being coded
-  **   pWInfo->a[].iTabCur   The VDBE cursor for the database table
-  **   pWInfo->a[].iIdxCur   The VDBE cursor for the index
-  **   pWInfo->a[].pTerm     When wsFlags==WO_OR, the OR-clause term
-  **
-  ** This loop also figures out the nesting order of tables in the FROM
-  ** clause.
-  */
-  sWBI.notValid = ~(Bitmask)0;
-  sWBI.pOrderBy = pOrderBy;
-  sWBI.n = nTabList;
-  sWBI.pDistinct = pDistinct;
-  andFlags = ~0;
-  WHERETRACE(("*** Optimizer Start ***\n"));
-  for(sWBI.i=iFrom=0, pLevel=pWInfo->a; sWBI.i<nTabList; sWBI.i++, pLevel++){
-    WhereCost bestPlan;         /* Most efficient plan seen so far */
-    Index *pIdx;                /* Index for FROM table at pTabItem */
-    int j;                      /* For looping over FROM tables */
-    int bestJ = -1;             /* The value of j */
-    Bitmask m;                  /* Bitmask value for j or bestJ */
-    int isOptimal;              /* Iterator for optimal/non-optimal search */
-    int ckOptimal;              /* Do the optimal scan check */
-    int nUnconstrained;         /* Number tables without INDEXED BY */
-    Bitmask notIndexed;         /* Mask of tables that cannot use an index */
-
-    memset(&bestPlan, 0, sizeof(bestPlan));
-    bestPlan.rCost = SQLITE_BIG_DBL;
-    WHERETRACE(("*** Begin search for loop %d ***\n", sWBI.i));
-
-    /* Loop through the remaining entries in the FROM clause to find the
-    ** next nested loop. The loop tests all FROM clause entries
-    ** either once or twice. 
-    **
-    ** The first test is always performed if there are two or more entries
-    ** remaining and never performed if there is only one FROM clause entry
-    ** to choose from.  The first test looks for an "optimal" scan.  In
-    ** this context an optimal scan is one that uses the same strategy
-    ** for the given FROM clause entry as would be selected if the entry
-    ** were used as the innermost nested loop.  In other words, a table
-    ** is chosen such that the cost of running that table cannot be reduced
-    ** by waiting for other tables to run first.  This "optimal" test works
-    ** by first assuming that the FROM clause is on the inner loop and finding
-    ** its query plan, then checking to see if that query plan uses any
-    ** other FROM clause terms that are sWBI.notValid.  If no notValid terms
-    ** are used then the "optimal" query plan works.
-    **
-    ** Note that the WhereCost.nRow parameter for an optimal scan might
-    ** not be as small as it would be if the table really were the innermost
-    ** join.  The nRow value can be reduced by WHERE clause constraints
-    ** that do not use indices.  But this nRow reduction only happens if the
-    ** table really is the innermost join.  
-    **
-    ** The second loop iteration is only performed if no optimal scan
-    ** strategies were found by the first iteration. This second iteration
-    ** is used to search for the lowest cost scan overall.
-    **
-    ** Without the optimal scan step (the first iteration) a suboptimal
-    ** plan might be chosen for queries like this:
-    **   
-    **   CREATE TABLE t1(a, b); 
-    **   CREATE TABLE t2(c, d);
-    **   SELECT * FROM t2, t1 WHERE t2.rowid = t1.a;
-    **
-    ** The best strategy is to iterate through table t1 first. However it
-    ** is not possible to determine this with a simple greedy algorithm.
-    ** Since the cost of a linear scan through table t2 is the same 
-    ** as the cost of a linear scan through table t1, a simple greedy 
-    ** algorithm may choose to use t2 for the outer loop, which is a much
-    ** costlier approach.
-    */
-    nUnconstrained = 0;
-    notIndexed = 0;
-
-    /* The optimal scan check only occurs if there are two or more tables
-    ** available to be reordered */
-    if( iFrom==nTabList-1 ){
-      ckOptimal = 0;  /* Common case of just one table in the FROM clause */
-    }else{
-      ckOptimal = -1;
-      for(j=iFrom, sWBI.pSrc=&pTabList->a[j]; j<nTabList; j++, sWBI.pSrc++){
-        m = getMask(pMaskSet, sWBI.pSrc->iCursor);
-        if( (m & sWBI.notValid)==0 ){
-          if( j==iFrom ) iFrom++;
-          continue;
-        }
-        if( j>iFrom && (sWBI.pSrc->jointype & (JT_LEFT|JT_CROSS))!=0 ) break;
-        if( ++ckOptimal ) break;
-        if( (sWBI.pSrc->jointype & JT_LEFT)!=0 ) break;
-      }
+  if( wctrlFlags & WHERE_WANT_DISTINCT ){
+    if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){
+      /* The DISTINCT marking is pointless.  Ignore it. */
+      pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
+    }else if( pOrderBy==0 ){
+      /* Try to ORDER BY the result set to make distinct processing easier */
+      pWInfo->wctrlFlags |= WHERE_DISTINCTBY;
+      pWInfo->pOrderBy = pResultSet;
     }
-    assert( ckOptimal==0 || ckOptimal==1 );
+  }
 
-    for(isOptimal=ckOptimal; isOptimal>=0 && bestJ<0; isOptimal--){
-      for(j=iFrom, sWBI.pSrc=&pTabList->a[j]; j<nTabList; j++, sWBI.pSrc++){
-        if( j>iFrom && (sWBI.pSrc->jointype & (JT_LEFT|JT_CROSS))!=0 ){
-          /* This break and one like it in the ckOptimal computation loop
-          ** above prevent table reordering across LEFT and CROSS JOINs.
-          ** The LEFT JOIN case is necessary for correctness.  The prohibition
-          ** against reordering across a CROSS JOIN is an SQLite feature that
-          ** allows the developer to control table reordering */
-          break;
-        }
-        m = getMask(pMaskSet, sWBI.pSrc->iCursor);
-        if( (m & sWBI.notValid)==0 ){
-          assert( j>iFrom );
-          continue;
-        }
-        sWBI.notReady = (isOptimal ? m : sWBI.notValid);
-        if( sWBI.pSrc->pIndex==0 ) nUnconstrained++;
+  /* Construct the WhereLoop objects */
+  WHERETRACE(0xffff,("*** Optimizer Start ***\n"));
+  if( nTabList!=1 || whereShortCut(&sWLB)==0 ){
+    rc = whereLoopAddAll(&sWLB);
+    if( rc ) goto whereBeginError;
   
-        WHERETRACE(("   === trying table %d (%s) with isOptimal=%d ===\n",
-                    j, sWBI.pSrc->pTab->zName, isOptimal));
-        assert( sWBI.pSrc->pTab );
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-        if( IsVirtual(sWBI.pSrc->pTab) ){
-          sWBI.ppIdxInfo = &pWInfo->a[j].pIdxInfo;
-          bestVirtualIndex(&sWBI);
-        }else 
-#endif
-        {
-          bestBtreeIndex(&sWBI);
-        }
-        assert( isOptimal || (sWBI.cost.used&sWBI.notValid)==0 );
-
-        /* If an INDEXED BY clause is present, then the plan must use that
-        ** index if it uses any index at all */
-        assert( sWBI.pSrc->pIndex==0 
-                  || (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0
-                  || sWBI.cost.plan.u.pIdx==sWBI.pSrc->pIndex );
-
-        if( isOptimal && (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){
-          notIndexed |= m;
-        }
-        if( isOptimal ){
-          pWInfo->a[j].rOptCost = sWBI.cost.rCost;
-        }else if( ckOptimal ){
-          /* If two or more tables have nearly the same outer loop cost, but
-          ** very different inner loop (optimal) cost, we want to choose
-          ** for the outer loop that table which benefits the least from
-          ** being in the inner loop.  The following code scales the 
-          ** outer loop cost estimate to accomplish that. */
-          WHERETRACE(("   scaling cost from %.1f to %.1f\n",
-                      sWBI.cost.rCost,
-                      sWBI.cost.rCost/pWInfo->a[j].rOptCost));
-          sWBI.cost.rCost /= pWInfo->a[j].rOptCost;
-        }
-
-        /* Conditions under which this table becomes the best so far:
-        **
-        **   (1) The table must not depend on other tables that have not
-        **       yet run.  (In other words, it must not depend on tables
-        **       in inner loops.)
-        **
-        **   (2) (This rule was removed on 2012-11-09.  The scaling of the
-        **       cost using the optimal scan cost made this rule obsolete.)
-        **
-        **   (3) All tables have an INDEXED BY clause or this table lacks an
-        **       INDEXED BY clause or this table uses the specific
-        **       index specified by its INDEXED BY clause.  This rule ensures
-        **       that a best-so-far is always selected even if an impossible
-        **       combination of INDEXED BY clauses are given.  The error
-        **       will be detected and relayed back to the application later.
-        **       The NEVER() comes about because rule (2) above prevents
-        **       An indexable full-table-scan from reaching rule (3).
-        **
-        **   (4) The plan cost must be lower than prior plans, where "cost"
-        **       is defined by the compareCost() function above. 
-        */
-        if( (sWBI.cost.used&sWBI.notValid)==0                    /* (1) */
-            && (nUnconstrained==0 || sWBI.pSrc->pIndex==0        /* (3) */
-                || NEVER((sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0))
-            && (bestJ<0 || compareCost(&sWBI.cost, &bestPlan))   /* (4) */
-        ){
-          WHERETRACE(("   === table %d (%s) is best so far\n"
-                      "       cost=%.1f, nRow=%.1f, nOBSat=%d, wsFlags=%08x\n",
-                      j, sWBI.pSrc->pTab->zName,
-                      sWBI.cost.rCost, sWBI.cost.plan.nRow,
-                      sWBI.cost.plan.nOBSat, sWBI.cost.plan.wsFlags));
-          bestPlan = sWBI.cost;
-          bestJ = j;
-        }
-
-        /* In a join like "w JOIN x LEFT JOIN y JOIN z"  make sure that
-        ** table y (and not table z) is always the next inner loop inside
-        ** of table x. */
-        if( (sWBI.pSrc->jointype & JT_LEFT)!=0 ) break;
-      }
-    }
-    assert( bestJ>=0 );
-    assert( sWBI.notValid & getMask(pMaskSet, pTabList->a[bestJ].iCursor) );
-    assert( bestJ==iFrom || (pTabList->a[iFrom].jointype & JT_LEFT)==0 );
-    testcase( bestJ>iFrom && (pTabList->a[iFrom].jointype & JT_CROSS)!=0 );
-    testcase( bestJ>iFrom && bestJ<nTabList-1
-                          && (pTabList->a[bestJ+1].jointype & JT_LEFT)!=0 );
-    WHERETRACE(("*** Optimizer selects table %d (%s) for loop %d with:\n"
-                "    cost=%.1f, nRow=%.1f, nOBSat=%d, wsFlags=0x%08x\n",
-                bestJ, pTabList->a[bestJ].pTab->zName,
-                pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow,
-                bestPlan.plan.nOBSat, bestPlan.plan.wsFlags));
-    if( (bestPlan.plan.wsFlags & WHERE_DISTINCT)!=0 ){
-      assert( pWInfo->eDistinct==0 );
-      pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
-    }
-    andFlags &= bestPlan.plan.wsFlags;
-    pLevel->plan = bestPlan.plan;
-    pLevel->iTabCur = pTabList->a[bestJ].iCursor;
-    testcase( bestPlan.plan.wsFlags & WHERE_INDEXED );
-    testcase( bestPlan.plan.wsFlags & WHERE_TEMP_INDEX );
-    if( bestPlan.plan.wsFlags & (WHERE_INDEXED|WHERE_TEMP_INDEX) ){
-      if( (wctrlFlags & WHERE_ONETABLE_ONLY) 
-       && (bestPlan.plan.wsFlags & WHERE_TEMP_INDEX)==0 
-      ){
-        pLevel->iIdxCur = iIdxCur;
-      }else{
-        pLevel->iIdxCur = pParse->nTab++;
+    /* Display all of the WhereLoop objects if wheretrace is enabled */
+#ifdef WHERETRACE_ENABLED
+    if( sqlite3WhereTrace ){
+      WhereLoop *p;
+      int i;
+      static char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz"
+                                       "ABCDEFGHIJKLMNOPQRSTUVWYXZ";
+      for(p=pWInfo->pLoops, i=0; p; p=p->pNextLoop, i++){
+        p->cId = zLabel[i%sizeof(zLabel)];
+        whereLoopPrint(p, pTabList);
       }
-    }else{
-      pLevel->iIdxCur = -1;
-    }
-    sWBI.notValid &= ~getMask(pMaskSet, pTabList->a[bestJ].iCursor);
-    pLevel->iFrom = (u8)bestJ;
-    if( bestPlan.plan.nRow>=(double)1 ){
-      pParse->nQueryLoop *= bestPlan.plan.nRow;
     }
-
-    /* Check that if the table scanned by this loop iteration had an
-    ** INDEXED BY clause attached to it, that the named index is being
-    ** used for the scan. If not, then query compilation has failed.
-    ** Return an error.
-    */
-    pIdx = pTabList->a[bestJ].pIndex;
-    if( pIdx ){
-      if( (bestPlan.plan.wsFlags & WHERE_INDEXED)==0 ){
-        sqlite3ErrorMsg(pParse, "cannot use index: %s", pIdx->zName);
-        goto whereBeginError;
-      }else{
-        /* If an INDEXED BY clause is used, the bestIndex() function is
-        ** guaranteed to find the index specified in the INDEXED BY clause
-        ** if it find an index at all. */
-        assert( bestPlan.plan.u.pIdx==pIdx );
-      }
+#endif
+  
+    wherePathSolver(pWInfo, 0);
+    if( db->mallocFailed ) goto whereBeginError;
+    if( pWInfo->pOrderBy ){
+       wherePathSolver(pWInfo, pWInfo->nRowOut+1);
+       if( db->mallocFailed ) goto whereBeginError;
     }
   }
-  WHERETRACE(("*** Optimizer Finished ***\n"));
-  if( pParse->nErr || db->mallocFailed ){
+  if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){
+     pWInfo->revMask = (Bitmask)(-1);
+  }
+  if( pParse->nErr || NEVER(db->mallocFailed) ){
     goto whereBeginError;
   }
-  if( nTabList ){
-    pLevel--;
-    pWInfo->nOBSat = pLevel->plan.nOBSat;
-  }else{
-    pWInfo->nOBSat = 0;
+#ifdef WHERETRACE_ENABLED
+  if( sqlite3WhereTrace ){
+    int ii;
+    sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut);
+    if( pWInfo->bOBSat ){
+      sqlite3DebugPrintf(" ORDERBY=0x%llx", pWInfo->revMask);
+    }
+    switch( pWInfo->eDistinct ){
+      case WHERE_DISTINCT_UNIQUE: {
+        sqlite3DebugPrintf("  DISTINCT=unique");
+        break;
+      }
+      case WHERE_DISTINCT_ORDERED: {
+        sqlite3DebugPrintf("  DISTINCT=ordered");
+        break;
+      }
+      case WHERE_DISTINCT_UNORDERED: {
+        sqlite3DebugPrintf("  DISTINCT=unordered");
+        break;
+      }
+    }
+    sqlite3DebugPrintf("\n");
+    for(ii=0; ii<pWInfo->nLevel; ii++){
+      whereLoopPrint(pWInfo->a[ii].pWLoop, pTabList);
+    }
   }
-
-  /* If the total query only selects a single row, then the ORDER BY
-  ** clause is irrelevant.
-  */
-  if( (andFlags & WHERE_UNIQUE)!=0 && pOrderBy ){
-    assert( nTabList==0 || (pLevel->plan.wsFlags & WHERE_ALL_UNIQUE)!=0 );
-    pWInfo->nOBSat = pOrderBy->nExpr;
+#endif
+  /* Attempt to omit tables from the join that do not effect the result */
+  if( pWInfo->nLevel>=2
+   && pResultSet!=0
+   && OptimizationEnabled(db, SQLITE_OmitNoopJoin)
+  ){
+    Bitmask tabUsed = exprListTableUsage(pMaskSet, pResultSet);
+    if( sWLB.pOrderBy ) tabUsed |= exprListTableUsage(pMaskSet, sWLB.pOrderBy);
+    while( pWInfo->nLevel>=2 ){
+      WhereTerm *pTerm, *pEnd;
+      pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop;
+      if( (pWInfo->pTabList->a[pLoop->iTab].jointype & JT_LEFT)==0 ) break;
+      if( (wctrlFlags & WHERE_WANT_DISTINCT)==0
+       && (pLoop->wsFlags & WHERE_ONEROW)==0
+      ){
+        break;
+      }
+      if( (tabUsed & pLoop->maskSelf)!=0 ) break;
+      pEnd = sWLB.pWC->a + sWLB.pWC->nTerm;
+      for(pTerm=sWLB.pWC->a; pTerm<pEnd; pTerm++){
+        if( (pTerm->prereqAll & pLoop->maskSelf)!=0
+         && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
+        ){
+          break;
+        }
+      }
+      if( pTerm<pEnd ) break;
+      WHERETRACE(0xffff, ("-> drop loop %c not used\n", pLoop->cId));
+      pWInfo->nLevel--;
+      nTabList--;
+    }
   }
+  WHERETRACE(0xffff,("*** Optimizer Finished ***\n"));
+  pWInfo->pParse->nQueryLoop += pWInfo->nRowOut;
 
   /* If the caller is an UPDATE or DELETE statement that is requesting
   ** to use a one-pass algorithm, determine if this is appropriate.
@@ -109892,17 +110756,16 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
   ** the statement to update a single row.
   */
   assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
-  if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 && (andFlags & WHERE_UNIQUE)!=0 ){
+  if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 
+   && (pWInfo->a[0].pWLoop->wsFlags & WHERE_ONEROW)!=0 ){
     pWInfo->okOnePass = 1;
-    pWInfo->a[0].plan.wsFlags &= ~WHERE_IDX_ONLY;
+    pWInfo->a[0].pWLoop->wsFlags &= ~WHERE_IDX_ONLY;
   }
 
   /* Open all tables in the pTabList and any indices selected for
   ** searching those tables.
   */
-  sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
   notReady = ~(Bitmask)0;
-  pWInfo->nRowOut = (double)1;
   for(ii=0, pLevel=pWInfo->a; ii<nTabList; ii++, pLevel++){
     Table *pTab;     /* Table to open */
     int iDb;         /* Index of database containing table/index */
@@ -109910,13 +110773,13 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
 
     pTabItem = &pTabList->a[pLevel->iFrom];
     pTab = pTabItem->pTab;
-    pWInfo->nRowOut *= pLevel->plan.nRow;
     iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+    pLoop = pLevel->pWLoop;
     if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){
       /* Do nothing */
     }else
 #ifndef SQLITE_OMIT_VIRTUALTABLE
-    if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
+    if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){
       const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
       int iCur = pTabItem->iCursor;
       sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB);
@@ -109924,12 +110787,12 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
       /* noop */
     }else
 #endif
-    if( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0
+    if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
          && (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){
       int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead;
       sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
-      testcase( pTab->nCol==BMS-1 );
-      testcase( pTab->nCol==BMS );
+      testcase( !pWInfo->okOnePass && pTab->nCol==BMS-1 );
+      testcase( !pWInfo->okOnePass && pTab->nCol==BMS );
       if( !pWInfo->okOnePass && pTab->nCol<BMS ){
         Bitmask b = pTabItem->colUsed;
         int n = 0;
@@ -109941,15 +110804,11 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
     }else{
       sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
     }
-#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
-    if( (pLevel->plan.wsFlags & WHERE_TEMP_INDEX)!=0 ){
-      constructAutomaticIndex(pParse, sWBI.pWC, pTabItem, notReady, pLevel);
-    }else
-#endif
-    if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){
-      Index *pIx = pLevel->plan.u.pIdx;
+    if( pLoop->wsFlags & WHERE_INDEXED ){
+      Index *pIx = pLoop->u.btree.pIndex;
       KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx);
-      int iIndexCur = pLevel->iIdxCur;
+      /* FIXME:  As an optimization use pTabItem->iCursor if WHERE_IDX_ONLY */
+      int iIndexCur = pLevel->iIdxCur = iIdxCur ? iIdxCur : pParse->nTab++;
       assert( pIx->pSchema==pTab->pSchema );
       assert( iIndexCur>=0 );
       sqlite3VdbeAddOp4(v, OP_OpenRead, iIndexCur, pIx->tnum, iDb,
@@ -109957,7 +110816,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
       VdbeComment((v, "%s", pIx->zName));
     }
     sqlite3CodeVerifySchema(pParse, iDb);
-    notReady &= ~getMask(sWBI.pWC->pMaskSet, pTabItem->iCursor);
+    notReady &= ~getMask(&pWInfo->sMaskSet, pTabItem->iCursor);
   }
   pWInfo->iTop = sqlite3VdbeCurrentAddr(v);
   if( db->mallocFailed ) goto whereBeginError;
@@ -109969,67 +110828,20 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
   notReady = ~(Bitmask)0;
   for(ii=0; ii<nTabList; ii++){
     pLevel = &pWInfo->a[ii];
+#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
+    if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){
+      constructAutomaticIndex(pParse, &pWInfo->sWC,
+                &pTabList->a[pLevel->iFrom], notReady, pLevel);
+      if( db->mallocFailed ) goto whereBeginError;
+    }
+#endif
     explainOneScan(pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags);
-    notReady = codeOneLoopStart(pWInfo, ii, wctrlFlags, notReady);
+    pLevel->addrBody = sqlite3VdbeCurrentAddr(v);
+    notReady = codeOneLoopStart(pWInfo, ii, notReady);
     pWInfo->iContinue = pLevel->addrCont;
   }
 
-#ifdef SQLITE_TEST  /* For testing and debugging use only */
-  /* Record in the query plan information about the current table
-  ** and the index used to access it (if any).  If the table itself
-  ** is not used, its name is just '{}'.  If no index is used
-  ** the index is listed as "{}".  If the primary key is used the
-  ** index name is '*'.
-  */
-  for(ii=0; ii<nTabList; ii++){
-    char *z;
-    int n;
-    int w;
-    struct SrcList_item *pTabItem;
-
-    pLevel = &pWInfo->a[ii];
-    w = pLevel->plan.wsFlags;
-    pTabItem = &pTabList->a[pLevel->iFrom];
-    z = pTabItem->zAlias;
-    if( z==0 ) z = pTabItem->pTab->zName;
-    n = sqlite3Strlen30(z);
-    if( n+nQPlan < sizeof(sqlite3_query_plan)-10 ){
-      if( (w & WHERE_IDX_ONLY)!=0 && (w & WHERE_COVER_SCAN)==0 ){
-        memcpy(&sqlite3_query_plan[nQPlan], "{}", 2);
-        nQPlan += 2;
-      }else{
-        memcpy(&sqlite3_query_plan[nQPlan], z, n);
-        nQPlan += n;
-      }
-      sqlite3_query_plan[nQPlan++] = ' ';
-    }
-    testcase( w & WHERE_ROWID_EQ );
-    testcase( w & WHERE_ROWID_RANGE );
-    if( w & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
-      memcpy(&sqlite3_query_plan[nQPlan], "* ", 2);
-      nQPlan += 2;
-    }else if( (w & WHERE_INDEXED)!=0 && (w & WHERE_COVER_SCAN)==0 ){
-      n = sqlite3Strlen30(pLevel->plan.u.pIdx->zName);
-      if( n+nQPlan < sizeof(sqlite3_query_plan)-2 ){
-        memcpy(&sqlite3_query_plan[nQPlan], pLevel->plan.u.pIdx->zName, n);
-        nQPlan += n;
-        sqlite3_query_plan[nQPlan++] = ' ';
-      }
-    }else{
-      memcpy(&sqlite3_query_plan[nQPlan], "{} ", 3);
-      nQPlan += 3;
-    }
-  }
-  while( nQPlan>0 && sqlite3_query_plan[nQPlan-1]==' ' ){
-    sqlite3_query_plan[--nQPlan] = 0;
-  }
-  sqlite3_query_plan[nQPlan] = 0;
-  nQPlan = 0;
-#endif /* SQLITE_TEST // Testing and debugging use only */
-
-  /* Record the continuation address in the WhereInfo structure.  Then
-  ** clean up and return.
-  */
+  /* Done. */
   return pWInfo;
 
   /* Jump here if malloc fails */
@@ -110050,6 +110862,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
   Vdbe *v = pParse->pVdbe;
   int i;
   WhereLevel *pLevel;
+  WhereLoop *pLoop;
   SrcList *pTabList = pWInfo->pTabList;
   sqlite3 *db = pParse->db;
 
@@ -110058,12 +110871,13 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
   sqlite3ExprCacheClear(pParse);
   for(i=pWInfo->nLevel-1; i>=0; i--){
     pLevel = &pWInfo->a[i];
+    pLoop = pLevel->pWLoop;
     sqlite3VdbeResolveLabel(v, pLevel->addrCont);
     if( pLevel->op!=OP_Noop ){
       sqlite3VdbeAddOp2(v, pLevel->op, pLevel->p1, pLevel->p2);
       sqlite3VdbeChangeP5(v, pLevel->p5);
     }
-    if( pLevel->plan.wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){
+    if( pLoop->wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){
       struct InLoop *pIn;
       int j;
       sqlite3VdbeResolveLabel(v, pLevel->addrNxt);
@@ -110078,12 +110892,12 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
     if( pLevel->iLeftJoin ){
       int addr;
       addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin);
-      assert( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0
-           || (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 );
-      if( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0 ){
+      assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
+           || (pLoop->wsFlags & WHERE_INDEXED)!=0 );
+      if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 ){
         sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor);
       }
-      if( pLevel->iIdxCur>=0 ){
+      if( pLoop->wsFlags & WHERE_INDEXED ){
         sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur);
       }
       if( pLevel->op==OP_Return ){
@@ -110102,31 +110916,30 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
 
   /* Close all of the cursors that were opened by sqlite3WhereBegin.
   */
-  assert( pWInfo->nLevel==1 || pWInfo->nLevel==pTabList->nSrc );
+  assert( pWInfo->nLevel<=pTabList->nSrc );
   for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){
     Index *pIdx = 0;
     struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom];
     Table *pTab = pTabItem->pTab;
     assert( pTab!=0 );
+    pLoop = pLevel->pWLoop;
     if( (pTab->tabFlags & TF_Ephemeral)==0
      && pTab->pSelect==0
      && (pWInfo->wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0
     ){
-      int ws = pLevel->plan.wsFlags;
+      int ws = pLoop->wsFlags;
       if( !pWInfo->okOnePass && (ws & WHERE_IDX_ONLY)==0 ){
         sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
       }
-      if( (ws & WHERE_INDEXED)!=0 && (ws & WHERE_TEMP_INDEX)==0 ){
+      if( (ws & WHERE_INDEXED)!=0 && (ws & (WHERE_IPK|WHERE_AUTO_INDEX))==0 ){
         sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);
       }
     }
 
-    /* If this scan uses an index, make code substitutions to read data
-    ** from the index in preference to the table. Sometimes, this means
-    ** the table need never be read from. This is a performance boost,
-    ** as the vdbe level waits until the table is read before actually
-    ** seeking the table cursor to the record corresponding to the current
-    ** position in the index.
+    /* If this scan uses an index, make VDBE code substitutions to read data
+    ** from the index instead of from the table where possible.  In some cases
+    ** this optimization prevents the table from ever being read, which can
+    ** yield a significant performance boost.
     ** 
     ** Calls to the code generator in between sqlite3WhereBegin and
     ** sqlite3WhereEnd will have created code that references the table
@@ -110134,18 +110947,19 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
     ** that reference the table and converts them into opcodes that
     ** reference the index.
     */
-    if( pLevel->plan.wsFlags & WHERE_INDEXED ){
-      pIdx = pLevel->plan.u.pIdx;
-    }else if( pLevel->plan.wsFlags & WHERE_MULTI_OR ){
+    if( pLoop->wsFlags & (WHERE_INDEXED|WHERE_IDX_ONLY) ){
+      pIdx = pLoop->u.btree.pIndex;
+    }else if( pLoop->wsFlags & WHERE_MULTI_OR ){
       pIdx = pLevel->u.pCovidx;
     }
-    if( pIdx && !db->mallocFailed){
+    if( pIdx && !db->mallocFailed ){
       int k, j, last;
       VdbeOp *pOp;
 
-      pOp = sqlite3VdbeGetOp(v, pWInfo->iTop);
       last = sqlite3VdbeCurrentAddr(v);
-      for(k=pWInfo->iTop; k<last; k++, pOp++){
+      k = pLevel->addrBody;
+      pOp = sqlite3VdbeGetOp(v, k);
+      for(; k<last; k++, pOp++){
         if( pOp->p1!=pLevel->iTabCur ) continue;
         if( pOp->opcode==OP_Column ){
           for(j=0; j<pIdx->nColumn; j++){
@@ -110155,8 +110969,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
               break;
             }
           }
-          assert( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0
-               || j<pIdx->nColumn );
+          assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || j<pIdx->nColumn );
         }else if( pOp->opcode==OP_Rowid ){
           pOp->p1 = pLevel->iIdxCur;
           pOp->opcode = OP_IdxRowid;
@@ -110394,7 +111207,7 @@ typedef union {
 #define sqlite3ParserARG_PDECL ,Parse *pParse
 #define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
 #define sqlite3ParserARG_STORE yypParser->pParse = pParse
-#define YYNSTATE 627
+#define YYNSTATE 628
 #define YYNRULE 327
 #define YYFALLBACK 1
 #define YY_NO_ACTION      (YYNSTATE+YYNRULE+2)
@@ -110467,163 +111280,163 @@ static const YYMINORTYPE yyzerominor = { 0 };
 */
 #define YY_ACTTAB_COUNT (1564)
 static const YYACTIONTYPE yy_action[] = {
- /*     0 */   309,  955,  184,  417,    2,  171,  624,  594,   56,   56,
+ /*     0 */   310,  956,  184,  418,    2,  171,  625,  595,   56,   56,
  /*    10 */    56,   56,   49,   54,   54,   54,   54,   53,   53,   52,
- /*    20 */    52,   52,   51,  233,  620,  619,  298,  620,  619,  234,
- /*    30 */   587,  581,   56,   56,   56,   56,   19,   54,   54,   54,
- /*    40 */    54,   53,   53,   52,   52,   52,   51,  233,  605,   57,
- /*    50 */    58,   48,  579,  578,  580,  580,   55,   55,   56,   56,
- /*    60 */    56,   56,  541,   54,   54,   54,   54,   53,   53,   52,
- /*    70 */    52,   52,   51,  233,  309,  594,  325,  196,  195,  194,
+ /*    20 */    52,   52,   51,  233,  621,  620,  299,  621,  620,  234,
+ /*    30 */   588,  582,   56,   56,   56,   56,   19,   54,   54,   54,
+ /*    40 */    54,   53,   53,   52,   52,   52,   51,  233,  606,   57,
+ /*    50 */    58,   48,  580,  579,  581,  581,   55,   55,   56,   56,
+ /*    60 */    56,   56,  542,   54,   54,   54,   54,   53,   53,   52,
+ /*    70 */    52,   52,   51,  233,  310,  595,  326,  196,  195,  194,
  /*    80 */    33,   54,   54,   54,   54,   53,   53,   52,   52,   52,
- /*    90 */    51,  233,  617,  616,  165,  617,  616,  380,  377,  376,
- /*   100 */   407,  532,  576,  576,  587,  581,  303,  422,  375,   59,
+ /*    90 */    51,  233,  618,  617,  165,  618,  617,  381,  378,  377,
+ /*   100 */   408,  533,  577,  577,  588,  582,  304,  423,  376,   59,
  /*   110 */    53,   53,   52,   52,   52,   51,  233,   50,   47,  146,
- /*   120 */   574,  545,   65,   57,   58,   48,  579,  578,  580,  580,
+ /*   120 */   575,  546,   65,   57,   58,   48,  580,  579,  581,  581,
  /*   130 */    55,   55,   56,   56,   56,   56,  213,   54,   54,   54,
- /*   140 */    54,   53,   53,   52,   52,   52,   51,  233,  309,  223,
- /*   150 */   539,  420,  170,  176,  138,  280,  383,  275,  382,  168,
- /*   160 */   489,  551,  409,  668,  620,  619,  271,  438,  409,  438,
- /*   170 */   550,  604,   67,  482,  507,  618,  599,  412,  587,  581,
- /*   180 */   600,  483,  618,  412,  618,  598,   91,  439,  440,  439,
- /*   190 */   335,  598,   73,  669,  222,  266,  480,   57,   58,   48,
- /*   200 */   579,  578,  580,  580,   55,   55,   56,   56,   56,   56,
- /*   210 */   670,   54,   54,   54,   54,   53,   53,   52,   52,   52,
- /*   220 */    51,  233,  309,  279,  232,  231,    1,  132,  200,  385,
- /*   230 */   620,  619,  617,  616,  278,  435,  289,  563,  175,  262,
- /*   240 */   409,  264,  437,  497,  436,  166,  441,  568,  336,  568,
- /*   250 */   201,  537,  587,  581,  599,  412,  165,  594,  600,  380,
- /*   260 */   377,  376,  597,  598,   92,  523,  618,  569,  569,  592,
- /*   270 */   375,   57,   58,   48,  579,  578,  580,  580,   55,   55,
- /*   280 */    56,   56,   56,   56,  597,   54,   54,   54,   54,   53,
- /*   290 */    53,   52,   52,   52,   51,  233,  309,  463,  617,  616,
- /*   300 */   590,  590,  590,  174,  272,  396,  409,  272,  409,  548,
- /*   310 */   397,  620,  619,   68,  326,  620,  619,  620,  619,  618,
- /*   320 */   546,  412,  618,  412,  471,  594,  587,  581,  472,  598,
- /*   330 */    92,  598,   92,   52,   52,   52,   51,  233,  513,  512,
- /*   340 */   206,  322,  363,  464,  221,   57,   58,   48,  579,  578,
- /*   350 */   580,  580,   55,   55,   56,   56,   56,   56,  529,   54,
+ /*   140 */    54,   53,   53,   52,   52,   52,   51,  233,  310,  223,
+ /*   150 */   540,  421,  170,  176,  138,  281,  384,  276,  383,  168,
+ /*   160 */   490,  552,  410,  669,  621,  620,  272,  439,  410,  439,
+ /*   170 */   551,  605,   67,  483,  508,  619,  600,  413,  588,  582,
+ /*   180 */   601,  484,  619,  413,  619,  599,   91,  440,  441,  440,
+ /*   190 */   336,  599,   73,  670,  222,  267,  481,   57,   58,   48,
+ /*   200 */   580,  579,  581,  581,   55,   55,   56,   56,   56,   56,
+ /*   210 */   671,   54,   54,   54,   54,   53,   53,   52,   52,   52,
+ /*   220 */    51,  233,  310,  280,  232,  231,    1,  132,  200,  386,
+ /*   230 */   621,  620,  618,  617,  279,  436,  290,  564,  175,  263,
+ /*   240 */   410,  265,  438,  498,  437,  166,  442,  569,  337,  569,
+ /*   250 */   201,  538,  588,  582,  600,  413,  165,  595,  601,  381,
+ /*   260 */   378,  377,  598,  599,   92,  524,  619,  570,  570,  593,
+ /*   270 */   376,   57,   58,   48,  580,  579,  581,  581,   55,   55,
+ /*   280 */    56,   56,   56,   56,  598,   54,   54,   54,   54,   53,
+ /*   290 */    53,   52,   52,   52,   51,  233,  310,  464,  618,  617,
+ /*   300 */   591,  591,  591,  174,  273,  397,  410,  273,  410,  549,
+ /*   310 */   398,  621,  620,   68,  327,  621,  620,  621,  620,  619,
+ /*   320 */   547,  413,  619,  413,  472,  595,  588,  582,  473,  599,
+ /*   330 */    92,  599,   92,   52,   52,   52,   51,  233,  514,  513,
+ /*   340 */   206,  323,  364,  465,  221,   57,   58,   48,  580,  579,
+ /*   350 */   581,  581,   55,   55,   56,   56,   56,   56,  530,   54,
  /*   360 */    54,   54,   54,   53,   53,   52,   52,   52,   51,  233,
- /*   370 */   309,  396,  409,  396,  597,  372,  386,  530,  347,  617,
- /*   380 */   616,  575,  202,  617,  616,  617,  616,  412,  620,  619,
- /*   390 */   145,  255,  346,  254,  577,  598,   74,  351,   45,  489,
- /*   400 */   587,  581,  235,  189,  464,  544,  167,  296,  187,  469,
- /*   410 */   479,   67,   62,   39,  618,  546,  597,  345,  573,   57,
- /*   420 */    58,   48,  579,  578,  580,  580,   55,   55,   56,   56,
+ /*   370 */   310,  397,  410,  397,  598,  373,  387,  531,  348,  618,
+ /*   380 */   617,  576,  202,  618,  617,  618,  617,  413,  621,  620,
+ /*   390 */   145,  255,  347,  254,  578,  599,   74,  352,   45,  490,
+ /*   400 */   588,  582,  235,  189,  465,  545,  167,  297,  187,  470,
+ /*   410 */   480,   67,   62,   39,  619,  547,  598,  346,  574,   57,
+ /*   420 */    58,   48,  580,  579,  581,  581,   55,   55,   56,   56,
  /*   430 */    56,   56,    6,   54,   54,   54,   54,   53,   53,   52,
- /*   440 */    52,   52,   51,  233,  309,  562,  558,  407,  528,  576,
- /*   450 */   576,  344,  255,  346,  254,  182,  617,  616,  503,  504,
- /*   460 */   314,  409,  557,  235,  166,  271,  409,  352,  564,  181,
- /*   470 */   407,  546,  576,  576,  587,  581,  412,  537,  556,  561,
- /*   480 */   517,  412,  618,  249,  598,   16,    7,   36,  467,  598,
- /*   490 */    92,  516,  618,   57,   58,   48,  579,  578,  580,  580,
- /*   500 */    55,   55,   56,   56,   56,   56,  541,   54,   54,   54,
- /*   510 */    54,   53,   53,   52,   52,   52,   51,  233,  309,  327,
- /*   520 */   572,  571,  525,  558,  560,  394,  871,  246,  409,  248,
- /*   530 */   171,  392,  594,  219,  407,  409,  576,  576,  502,  557,
- /*   540 */   364,  145,  510,  412,  407,  229,  576,  576,  587,  581,
- /*   550 */   412,  598,   92,  381,  269,  556,  166,  400,  598,   69,
- /*   560 */   501,  419,  945,  199,  945,  198,  546,   57,   58,   48,
- /*   570 */   579,  578,  580,  580,   55,   55,   56,   56,   56,   56,
- /*   580 */   568,   54,   54,   54,   54,   53,   53,   52,   52,   52,
- /*   590 */    51,  233,  309,  317,  419,  944,  508,  944,  308,  597,
- /*   600 */   594,  565,  490,  212,  173,  247,  423,  615,  614,  613,
- /*   610 */   323,  197,  143,  405,  572,  571,  489,   66,   50,   47,
- /*   620 */   146,  594,  587,  581,  232,  231,  559,  427,   67,  555,
- /*   630 */    15,  618,  186,  543,  303,  421,   35,  206,  432,  423,
- /*   640 */   552,   57,   58,   48,  579,  578,  580,  580,   55,   55,
+ /*   440 */    52,   52,   51,  233,  310,  563,  559,  408,  529,  577,
+ /*   450 */   577,  345,  255,  347,  254,  182,  618,  617,  504,  505,
+ /*   460 */   315,  410,  558,  235,  166,  272,  410,  353,  565,  181,
+ /*   470 */   408,  547,  577,  577,  588,  582,  413,  538,  557,  562,
+ /*   480 */   518,  413,  619,  249,  599,   16,    7,   36,  468,  599,
+ /*   490 */    92,  517,  619,   57,   58,   48,  580,  579,  581,  581,
+ /*   500 */    55,   55,   56,   56,   56,   56,  542,   54,   54,   54,
+ /*   510 */    54,   53,   53,   52,   52,   52,   51,  233,  310,  328,
+ /*   520 */   573,  572,  526,  559,  561,  395,  872,  246,  410,  248,
+ /*   530 */   171,  393,  595,  219,  408,  410,  577,  577,  503,  558,
+ /*   540 */   365,  145,  511,  413,  408,  229,  577,  577,  588,  582,
+ /*   550 */   413,  599,   92,  382,  270,  557,  166,  401,  599,   69,
+ /*   560 */   502,  420,  946,  199,  946,  198,  547,   57,   58,   48,
+ /*   570 */   580,  579,  581,  581,   55,   55,   56,   56,   56,   56,
+ /*   580 */   569,   54,   54,   54,   54,   53,   53,   52,   52,   52,
+ /*   590 */    51,  233,  310,  318,  420,  945,  509,  945,  309,  598,
+ /*   600 */   595,  566,  491,  212,  173,  247,  424,  616,  615,  614,
+ /*   610 */   324,  197,  143,  406,  573,  572,  490,   66,   50,   47,
+ /*   620 */   146,  595,  588,  582,  232,  231,  560,  428,   67,  556,
+ /*   630 */    15,  619,  186,  544,  304,  422,   35,  206,  433,  424,
+ /*   640 */   553,   57,   58,   48,  580,  579,  581,  581,   55,   55,
  /*   650 */    56,   56,   56,   56,  205,   54,   54,   54,   54,   53,
- /*   660 */    53,   52,   52,   52,   51,  233,  309,  569,  569,  260,
- /*   670 */   268,  597,   12,  373,  568,  166,  409,  313,  409,  420,
- /*   680 */   409,  473,  473,  365,  618,   50,   47,  146,  597,  594,
- /*   690 */   468,  412,  166,  412,  351,  412,  587,  581,   32,  598,
- /*   700 */    94,  598,   97,  598,   95,  627,  625,  329,  142,   50,
- /*   710 */    47,  146,  333,  349,  358,   57,   58,   48,  579,  578,
- /*   720 */   580,  580,   55,   55,   56,   56,   56,   56,  409,   54,
+ /*   660 */    53,   52,   52,   52,   51,  233,  310,  570,  570,  261,
+ /*   670 */   269,  598,   12,  374,  569,  166,  410,  314,  410,  421,
+ /*   680 */   410,  474,  474,  366,  619,   50,   47,  146,  598,  595,
+ /*   690 */   256,  413,  166,  413,  352,  413,  588,  582,   32,  599,
+ /*   700 */    94,  599,   97,  599,   95,  628,  626,  330,  142,   50,
+ /*   710 */    47,  146,  334,  350,  359,   57,   58,   48,  580,  579,
+ /*   720 */   581,  581,   55,   55,   56,   56,   56,   56,  410,   54,
  /*   730 */    54,   54,   54,   53,   53,   52,   52,   52,   51,  233,
- /*   740 */   309,  409,  388,  412,  409,   22,  565,  404,  212,  362,
- /*   750 */   389,  598,  104,  359,  409,  156,  412,  409,  603,  412,
- /*   760 */   537,  331,  569,  569,  598,  103,  493,  598,  105,  412,
- /*   770 */   587,  581,  412,  260,  549,  618,   11,  598,  106,  521,
- /*   780 */   598,  133,  169,  457,  456,  170,   35,  601,  618,   57,
- /*   790 */    58,   48,  579,  578,  580,  580,   55,   55,   56,   56,
- /*   800 */    56,   56,  409,   54,   54,   54,   54,   53,   53,   52,
- /*   810 */    52,   52,   51,  233,  309,  409,  259,  412,  409,   50,
- /*   820 */    47,  146,  357,  318,  355,  598,  134,  527,  352,  337,
- /*   830 */   412,  409,  356,  412,  357,  409,  357,  618,  598,   98,
- /*   840 */   129,  598,  102,  618,  587,  581,  412,   21,  235,  618,
- /*   850 */   412,  618,  211,  143,  598,  101,   30,  167,  598,   93,
- /*   860 */   350,  535,  203,   57,   58,   48,  579,  578,  580,  580,
- /*   870 */    55,   55,   56,   56,   56,   56,  409,   54,   54,   54,
- /*   880 */    54,   53,   53,   52,   52,   52,   51,  233,  309,  409,
- /*   890 */   526,  412,  409,  425,  215,  305,  597,  551,  141,  598,
- /*   900 */   100,   40,  409,   38,  412,  409,  550,  412,  409,  228,
- /*   910 */   220,  314,  598,   77,  500,  598,   96,  412,  587,  581,
- /*   920 */   412,  338,  253,  412,  218,  598,  137,  379,  598,  136,
- /*   930 */    28,  598,  135,  270,  715,  210,  481,   57,   58,   48,
- /*   940 */   579,  578,  580,  580,   55,   55,   56,   56,   56,   56,
- /*   950 */   409,   54,   54,   54,   54,   53,   53,   52,   52,   52,
- /*   960 */    51,  233,  309,  409,  272,  412,  409,  315,  147,  597,
- /*   970 */   272,  626,    2,  598,   76,  209,  409,  127,  412,  618,
- /*   980 */   126,  412,  409,  621,  235,  618,  598,   90,  374,  598,
- /*   990 */    89,  412,  587,  581,   27,  260,  350,  412,  618,  598,
- /*  1000 */    75,  321,  541,  541,  125,  598,   88,  320,  278,  597,
- /*  1010 */   618,   57,   46,   48,  579,  578,  580,  580,   55,   55,
- /*  1020 */    56,   56,   56,   56,  409,   54,   54,   54,   54,   53,
- /*  1030 */    53,   52,   52,   52,   51,  233,  309,  409,  450,  412,
- /*  1040 */   164,  284,  282,  272,  609,  424,  304,  598,   87,  370,
- /*  1050 */   409,  477,  412,  409,  608,  409,  607,  602,  618,  618,
- /*  1060 */   598,   99,  586,  585,  122,  412,  587,  581,  412,  618,
- /*  1070 */   412,  618,  618,  598,   86,  366,  598,   17,  598,   85,
- /*  1080 */   319,  185,  519,  518,  583,  582,   58,   48,  579,  578,
- /*  1090 */   580,  580,   55,   55,   56,   56,   56,   56,  409,   54,
+ /*   740 */   310,  410,  389,  413,  410,   22,  566,  405,  212,  363,
+ /*   750 */   390,  599,  104,  360,  410,  156,  413,  410,  604,  413,
+ /*   760 */   538,  332,  570,  570,  599,  103,  494,  599,  105,  413,
+ /*   770 */   588,  582,  413,  261,  550,  619,   11,  599,  106,  522,
+ /*   780 */   599,  133,  169,  458,  457,  170,   35,  602,  619,   57,
+ /*   790 */    58,   48,  580,  579,  581,  581,   55,   55,   56,   56,
+ /*   800 */    56,   56,  410,   54,   54,   54,   54,   53,   53,   52,
+ /*   810 */    52,   52,   51,  233,  310,  410,  260,  413,  410,   50,
+ /*   820 */    47,  146,  358,  319,  356,  599,  134,  528,  353,  338,
+ /*   830 */   413,  410,  357,  413,  358,  410,  358,  619,  599,   98,
+ /*   840 */   129,  599,  102,  619,  588,  582,  413,   21,  235,  619,
+ /*   850 */   413,  619,  211,  143,  599,  101,   30,  167,  599,   93,
+ /*   860 */   351,  536,  203,   57,   58,   48,  580,  579,  581,  581,
+ /*   870 */    55,   55,   56,   56,   56,   56,  410,   54,   54,   54,
+ /*   880 */    54,   53,   53,   52,   52,   52,   51,  233,  310,  410,
+ /*   890 */   527,  413,  410,  426,  215,  306,  598,  552,  141,  599,
+ /*   900 */   100,   40,  410,   38,  413,  410,  551,  413,  410,  228,
+ /*   910 */   220,  315,  599,   77,  501,  599,   96,  413,  588,  582,
+ /*   920 */   413,  339,  253,  413,  218,  599,  137,  380,  599,  136,
+ /*   930 */    28,  599,  135,  271,  716,  210,  482,   57,   58,   48,
+ /*   940 */   580,  579,  581,  581,   55,   55,   56,   56,   56,   56,
+ /*   950 */   410,   54,   54,   54,   54,   53,   53,   52,   52,   52,
+ /*   960 */    51,  233,  310,  410,  273,  413,  410,  316,  147,  598,
+ /*   970 */   273,  627,    2,  599,   76,  209,  410,  127,  413,  619,
+ /*   980 */   126,  413,  410,  622,  235,  619,  599,   90,  375,  599,
+ /*   990 */    89,  413,  588,  582,   27,  261,  351,  413,  619,  599,
+ /*  1000 */    75,  322,  542,  542,  125,  599,   88,  321,  279,  598,
+ /*  1010 */   619,   57,   46,   48,  580,  579,  581,  581,   55,   55,
+ /*  1020 */    56,   56,   56,   56,  410,   54,   54,   54,   54,   53,
+ /*  1030 */    53,   52,   52,   52,   51,  233,  310,  410,  451,  413,
+ /*  1040 */   164,  285,  283,  273,  610,  425,  305,  599,   87,  371,
+ /*  1050 */   410,  478,  413,  410,  609,  410,  608,  603,  619,  619,
+ /*  1060 */   599,   99,  587,  586,  122,  413,  588,  582,  413,  619,
+ /*  1070 */   413,  619,  619,  599,   86,  367,  599,   17,  599,   85,
+ /*  1080 */   320,  185,  520,  519,  584,  583,   58,   48,  580,  579,
+ /*  1090 */   581,  581,   55,   55,   56,   56,   56,   56,  410,   54,
  /*  1100 */    54,   54,   54,   53,   53,   52,   52,   52,   51,  233,
- /*  1110 */   309,  584,  409,  412,  409,  260,  260,  260,  408,  591,
- /*  1120 */   474,  598,   84,  170,  409,  466,  518,  412,  121,  412,
- /*  1130 */   618,  618,  618,  618,  618,  598,   83,  598,   72,  412,
- /*  1140 */   587,  581,   51,  233,  625,  329,  470,  598,   71,  257,
- /*  1150 */   159,  120,   14,  462,  157,  158,  117,  260,  448,  447,
- /*  1160 */   446,   48,  579,  578,  580,  580,   55,   55,   56,   56,
- /*  1170 */    56,   56,  618,   54,   54,   54,   54,   53,   53,   52,
- /*  1180 */    52,   52,   51,  233,   44,  403,  260,    3,  409,  459,
- /*  1190 */   260,  413,  619,  118,  398,   10,   25,   24,  554,  348,
- /*  1200 */   217,  618,  406,  412,  409,  618,    4,   44,  403,  618,
- /*  1210 */     3,  598,   82,  618,  413,  619,  455,  542,  115,  412,
- /*  1220 */   538,  401,  536,  274,  506,  406,  251,  598,   81,  216,
- /*  1230 */   273,  563,  618,  243,  453,  618,  154,  618,  618,  618,
- /*  1240 */   449,  416,  623,  110,  401,  618,  409,  236,   64,  123,
- /*  1250 */   487,   41,   42,  531,  563,  204,  409,  267,   43,  411,
- /*  1260 */   410,  412,  265,  592,  108,  618,  107,  434,  332,  598,
- /*  1270 */    80,  412,  618,  263,   41,   42,  443,  618,  409,  598,
- /*  1280 */    70,   43,  411,  410,  433,  261,  592,  149,  618,  597,
- /*  1290 */   256,  237,  188,  412,  590,  590,  590,  589,  588,   13,
- /*  1300 */   618,  598,   18,  328,  235,  618,   44,  403,  360,    3,
- /*  1310 */   418,  461,  339,  413,  619,  227,  124,  590,  590,  590,
- /*  1320 */   589,  588,   13,  618,  406,  409,  618,  409,  139,   34,
- /*  1330 */   403,  387,    3,  148,  622,  312,  413,  619,  311,  330,
- /*  1340 */   412,  460,  412,  401,  180,  353,  412,  406,  598,   79,
- /*  1350 */   598,   78,  250,  563,  598,    9,  618,  612,  611,  610,
- /*  1360 */   618,    8,  452,  442,  242,  415,  401,  618,  239,  235,
- /*  1370 */   179,  238,  428,   41,   42,  288,  563,  618,  618,  618,
- /*  1380 */    43,  411,  410,  618,  144,  592,  618,  618,  177,   61,
- /*  1390 */   618,  596,  391,  620,  619,  287,   41,   42,  414,  618,
- /*  1400 */   293,   30,  393,   43,  411,  410,  292,  618,  592,   31,
- /*  1410 */   618,  395,  291,   60,  230,   37,  590,  590,  590,  589,
- /*  1420 */   588,   13,  214,  553,  183,  290,  172,  301,  300,  299,
- /*  1430 */   178,  297,  595,  563,  451,   29,  285,  390,  540,  590,
- /*  1440 */   590,  590,  589,  588,   13,  283,  520,  534,  150,  533,
- /*  1450 */   241,  281,  384,  192,  191,  324,  515,  514,  276,  240,
- /*  1460 */   510,  523,  307,  511,  128,  592,  509,  225,  226,  486,
- /*  1470 */   485,  224,  152,  491,  464,  306,  484,  163,  153,  371,
- /*  1480 */   478,  151,  162,  258,  369,  161,  367,  208,  475,  476,
- /*  1490 */    26,  160,  465,  140,  361,  131,  590,  590,  590,  116,
- /*  1500 */   119,  454,  343,  155,  114,  342,  113,  112,  445,  111,
- /*  1510 */   130,  109,  431,  316,  426,  430,   23,  429,   20,  606,
- /*  1520 */   190,  507,  255,  341,  244,   63,  294,  593,  310,  570,
- /*  1530 */   277,  402,  354,  235,  567,  496,  495,  492,  494,  302,
- /*  1540 */   458,  378,  286,  245,  566,    5,  252,  547,  193,  444,
- /*  1550 */   233,  340,  207,  524,  368,  505,  334,  522,  499,  399,
- /*  1560 */   295,  498,  956,  488,
+ /*  1110 */   310,  585,  410,  413,  410,  261,  261,  261,  409,  592,
+ /*  1120 */   475,  599,   84,  170,  410,  467,  519,  413,  121,  413,
+ /*  1130 */   619,  619,  619,  619,  619,  599,   83,  599,   72,  413,
+ /*  1140 */   588,  582,   51,  233,  626,  330,  471,  599,   71,  258,
+ /*  1150 */   159,  120,   14,  463,  157,  158,  117,  261,  449,  448,
+ /*  1160 */   447,   48,  580,  579,  581,  581,   55,   55,   56,   56,
+ /*  1170 */    56,   56,  619,   54,   54,   54,   54,   53,   53,   52,
+ /*  1180 */    52,   52,   51,  233,   44,  404,  261,    3,  410,  460,
+ /*  1190 */   261,  414,  620,  118,  399,   10,   25,   24,  555,  349,
+ /*  1200 */   217,  619,  407,  413,  410,  619,    4,   44,  404,  619,
+ /*  1210 */     3,  599,   82,  619,  414,  620,  456,  543,  115,  413,
+ /*  1220 */   539,  402,  537,  275,  507,  407,  251,  599,   81,  216,
+ /*  1230 */   274,  564,  619,  243,  454,  619,  154,  619,  619,  619,
+ /*  1240 */   450,  417,  624,  110,  402,  619,  410,  236,   64,  123,
+ /*  1250 */   488,   41,   42,  532,  564,  204,  410,  268,   43,  412,
+ /*  1260 */   411,  413,  266,  593,  108,  619,  107,  435,  333,  599,
+ /*  1270 */    80,  413,  619,  264,   41,   42,  444,  619,  410,  599,
+ /*  1280 */    70,   43,  412,  411,  434,  262,  593,  149,  619,  598,
+ /*  1290 */   257,  237,  188,  413,  591,  591,  591,  590,  589,   13,
+ /*  1300 */   619,  599,   18,  329,  235,  619,   44,  404,  361,    3,
+ /*  1310 */   419,  462,  340,  414,  620,  227,  124,  591,  591,  591,
+ /*  1320 */   590,  589,   13,  619,  407,  410,  619,  410,  139,   34,
+ /*  1330 */   404,  388,    3,  148,  623,  313,  414,  620,  312,  331,
+ /*  1340 */   413,  461,  413,  402,  180,  354,  413,  407,  599,   79,
+ /*  1350 */   599,   78,  250,  564,  599,    9,  619,  613,  612,  611,
+ /*  1360 */   619,    8,  453,  443,  242,  416,  402,  619,  239,  235,
+ /*  1370 */   179,  238,  429,   41,   42,  289,  564,  619,  619,  619,
+ /*  1380 */    43,  412,  411,  619,  144,  593,  619,  619,  177,   61,
+ /*  1390 */   619,  597,  392,  621,  620,  288,   41,   42,  415,  619,
+ /*  1400 */   294,   30,  394,   43,  412,  411,  293,  619,  593,   31,
+ /*  1410 */   619,  396,  292,   60,  230,   37,  591,  591,  591,  590,
+ /*  1420 */   589,   13,  214,  554,  183,  291,  172,  302,  301,  300,
+ /*  1430 */   178,  298,  596,  564,  452,   29,  286,  391,  541,  591,
+ /*  1440 */   591,  591,  590,  589,   13,  284,  521,  535,  150,  534,
+ /*  1450 */   241,  282,  385,  192,  191,  325,  516,  515,  277,  240,
+ /*  1460 */   511,  524,  308,  512,  128,  593,  510,  225,  226,  487,
+ /*  1470 */   486,  224,  152,  492,  465,  307,  485,  163,  153,  372,
+ /*  1480 */   479,  151,  162,  259,  370,  161,  368,  208,  476,  477,
+ /*  1490 */    26,  160,  469,  466,  362,  140,  591,  591,  591,  116,
+ /*  1500 */   119,  455,  344,  155,  114,  343,  113,  112,  446,  111,
+ /*  1510 */   131,  109,  432,  317,  130,  431,   23,   20,  430,  427,
+ /*  1520 */   190,   63,  255,  342,  244,  607,  295,  287,  311,  594,
+ /*  1530 */   278,  508,  496,  235,  493,  571,  497,  568,  495,  403,
+ /*  1540 */   459,  379,  355,  245,  193,  303,  567,  296,  341,    5,
+ /*  1550 */   445,  548,  506,  207,  525,  500,  335,  489,  252,  369,
+ /*  1560 */   400,  499,  523,  233,
 };
 static const YYCODETYPE yy_lookahead[] = {
  /*     0 */    19,  142,  143,  144,  145,   24,    1,   26,   77,   78,
@@ -110775,17 +111588,17 @@ static const YYCODETYPE yy_lookahead[] = {
  /*  1460 */   103,   94,  178,  177,   22,   98,  175,   92,  228,  175,
  /*  1470 */   175,  228,   55,  183,   57,  178,  175,  156,   61,   18,
  /*  1480 */   157,   64,  156,  235,  157,  156,   45,  157,  236,  157,
- /*  1490 */   135,  156,  189,   68,  157,  218,  129,  130,  131,   22,
+ /*  1490 */   135,  156,  199,  189,  157,   68,  129,  130,  131,   22,
  /*  1500 */   189,  199,  157,  156,  192,   18,  192,  192,  199,  192,
- /*  1510 */   218,  189,   40,  157,   38,  157,  240,  157,  240,  153,
- /*  1520 */   196,  181,  105,  106,  107,  243,  198,  166,  111,  230,
- /*  1530 */   176,  226,  239,  116,  230,  176,  166,  166,  176,  148,
- /*  1540 */   199,  177,  209,  209,  166,  196,  239,  208,  185,  199,
- /*  1550 */    92,  209,  233,  173,  234,  182,  139,  173,  182,  191,
- /*  1560 */   195,  182,  250,  186,
+ /*  1510 */   218,  189,   40,  157,  218,  157,  240,  240,  157,   38,
+ /*  1520 */   196,  243,  105,  106,  107,  153,  198,  209,  111,  166,
+ /*  1530 */   176,  181,  166,  116,  166,  230,  176,  230,  176,  226,
+ /*  1540 */   199,  177,  239,  209,  185,  148,  166,  195,  209,  196,
+ /*  1550 */   199,  208,  182,  233,  173,  182,  139,  186,  239,  234,
+ /*  1560 */   191,  182,  173,   92,
 };
 #define YY_SHIFT_USE_DFLT (-70)
-#define YY_SHIFT_COUNT (416)
+#define YY_SHIFT_COUNT (417)
 #define YY_SHIFT_MIN   (-69)
 #define YY_SHIFT_MAX   (1487)
 static const short yy_shift_ofst[] = {
@@ -110802,7 +111615,7 @@ static const short yy_shift_ofst[] = {
  /*   100 */   -45,  -45,  -45,  -45,   -1,   24,  245,  362,  362,  362,
  /*   110 */   362,  362,  362,  362,  362,  362,  362,  362,  362,  362,
  /*   120 */   362,  362,  362,  388,  356,  362,  362,  362,  362,  362,
- /*   130 */   732,  868,  231, 1051, 1458,  -70,  -70,  -70, 1367,   57,
+ /*   130 */   732,  868,  231, 1051, 1471,  -70,  -70,  -70, 1367,   57,
  /*   140 */   434,  434,  289,  291,  285,    1,  204,  572,  539,  362,
  /*   150 */   362,  362,  362,  362,  362,  362,  362,  362,  362,  362,
  /*   160 */   362,  362,  362,  362,  362,  362,  362,  362,  362,  362,
@@ -110812,30 +111625,30 @@ static const short yy_shift_ofst[] = {
  /*   200 */   422,  358,  335,  -12,  -12,  -12,  -12,  576,  294,  -12,
  /*   210 */   -12,  295,  595,  141,  600,  730,  723,  723,  805,  730,
  /*   220 */   805,  439,  911,  231,  865,  231,  865,  807,  865,  723,
- /*   230 */   766,  633,  633,  231,  284,   63,  608, 1476, 1308, 1308,
- /*   240 */  1472, 1472, 1308, 1477, 1425, 1275, 1487, 1487, 1487, 1487,
- /*   250 */  1308, 1461, 1275, 1477, 1425, 1425, 1308, 1461, 1355, 1441,
- /*   260 */  1308, 1308, 1461, 1308, 1461, 1308, 1461, 1442, 1348, 1348,
- /*   270 */  1348, 1408, 1375, 1375, 1442, 1348, 1357, 1348, 1408, 1348,
- /*   280 */  1348, 1316, 1331, 1316, 1331, 1316, 1331, 1308, 1308, 1280,
- /*   290 */  1288, 1289, 1285, 1279, 1275, 1253, 1336, 1346, 1346, 1338,
- /*   300 */  1338, 1338, 1338,  -70,  -70,  -70,  -70,  -70,  -70, 1013,
- /*   310 */   467,  612,   84,  179,  -28,  870,  410,  761,  760,  667,
- /*   320 */   650,  531,  220,  361,  331,  125,  127,   97, 1306, 1300,
- /*   330 */  1270, 1151, 1272, 1203, 1232, 1261, 1244, 1148, 1174, 1139,
- /*   340 */  1156, 1124, 1220, 1115, 1210, 1233, 1099, 1193, 1184, 1174,
- /*   350 */  1173, 1029, 1121, 1120, 1085, 1162, 1119, 1037, 1152, 1147,
- /*   360 */  1129, 1046, 1011, 1093, 1098, 1075, 1061, 1032,  960, 1057,
- /*   370 */  1031, 1030,  899,  938,  982,  936,  972,  958,  910,  955,
- /*   380 */   875,  885,  908,  857,  859,  867,  804,  590,  834,  747,
- /*   390 */   818,  513,  611,  741,  673,  637,  611,  606,  603,  579,
- /*   400 */   501,  541,  468,  386,  445,  395,  376,  281,  185,  120,
- /*   410 */    92,   75,   45,  114,   25,   11,    5,
+ /*   230 */   766,  633,  633,  231,  284,   63,  608, 1481, 1308, 1308,
+ /*   240 */  1472, 1472, 1308, 1477, 1427, 1275, 1487, 1487, 1487, 1487,
+ /*   250 */  1308, 1461, 1275, 1477, 1427, 1427, 1275, 1308, 1461, 1355,
+ /*   260 */  1441, 1308, 1308, 1461, 1308, 1461, 1308, 1461, 1442, 1348,
+ /*   270 */  1348, 1348, 1408, 1375, 1375, 1442, 1348, 1357, 1348, 1408,
+ /*   280 */  1348, 1348, 1316, 1331, 1316, 1331, 1316, 1331, 1308, 1308,
+ /*   290 */  1280, 1288, 1289, 1285, 1279, 1275, 1253, 1336, 1346, 1346,
+ /*   300 */  1338, 1338, 1338, 1338,  -70,  -70,  -70,  -70,  -70,  -70,
+ /*   310 */  1013,  467,  612,   84,  179,  -28,  870,  410,  761,  760,
+ /*   320 */   667,  650,  531,  220,  361,  331,  125,  127,   97, 1306,
+ /*   330 */  1300, 1270, 1151, 1272, 1203, 1232, 1261, 1244, 1148, 1174,
+ /*   340 */  1139, 1156, 1124, 1220, 1115, 1210, 1233, 1099, 1193, 1184,
+ /*   350 */  1174, 1173, 1029, 1121, 1120, 1085, 1162, 1119, 1037, 1152,
+ /*   360 */  1147, 1129, 1046, 1011, 1093, 1098, 1075, 1061, 1032,  960,
+ /*   370 */  1057, 1031, 1030,  899,  938,  982,  936,  972,  958,  910,
+ /*   380 */   955,  875,  885,  908,  857,  859,  867,  804,  590,  834,
+ /*   390 */   747,  818,  513,  611,  741,  673,  637,  611,  606,  603,
+ /*   400 */   579,  501,  541,  468,  386,  445,  395,  376,  281,  185,
+ /*   410 */   120,   92,   75,   45,  114,   25,   11,    5,
 };
 #define YY_REDUCE_USE_DFLT (-169)
-#define YY_REDUCE_COUNT (308)
+#define YY_REDUCE_COUNT (309)
 #define YY_REDUCE_MIN   (-168)
-#define YY_REDUCE_MAX   (1391)
+#define YY_REDUCE_MAX   (1397)
 static const short yy_reduce_ofst[] = {
  /*     0 */  -141,   90, 1095,  222,  158,  156,   19,   17,   10, -104,
  /*    10 */   378,  316,  311,   12,  180,  249,  598,  464,  397, 1181,
@@ -110856,83 +111669,83 @@ static const short yy_reduce_ofst[] = {
  /*   160 */  1140, 1135, 1123, 1112, 1107, 1100, 1080, 1074, 1073, 1072,
  /*   170 */  1070, 1067, 1048, 1044,  969,  968,  907,  906,  904,  894,
  /*   180 */   833,  837,  836,  340,  827,  815,  775,   68,  722,  646,
- /*   190 */  -168, 1384, 1380, 1377, 1379, 1376, 1373, 1339, 1365, 1368,
- /*   200 */  1365, 1365, 1365, 1365, 1365, 1365, 1365, 1320, 1319, 1365,
- /*   210 */  1365, 1339, 1378, 1349, 1391, 1350, 1342, 1334, 1307, 1341,
- /*   220 */  1293, 1364, 1363, 1371, 1362, 1370, 1359, 1340, 1354, 1333,
- /*   230 */  1305, 1304, 1299, 1361, 1328, 1324, 1366, 1282, 1360, 1358,
- /*   240 */  1278, 1276, 1356, 1292, 1322, 1309, 1317, 1315, 1314, 1312,
- /*   250 */  1345, 1347, 1302, 1277, 1311, 1303, 1337, 1335, 1252, 1248,
- /*   260 */  1332, 1330, 1329, 1327, 1326, 1323, 1321, 1297, 1301, 1295,
- /*   270 */  1294, 1290, 1243, 1240, 1284, 1291, 1286, 1283, 1274, 1281,
- /*   280 */  1271, 1238, 1241, 1236, 1235, 1227, 1226, 1267, 1266, 1189,
- /*   290 */  1229, 1223, 1211, 1206, 1201, 1197, 1239, 1237, 1219, 1216,
- /*   300 */  1209, 1208, 1185, 1089, 1086, 1087, 1137, 1136, 1164,
+ /*   190 */  -168, 1389, 1381, 1371, 1379, 1373, 1370, 1343, 1352, 1369,
+ /*   200 */  1352, 1352, 1352, 1352, 1352, 1352, 1352, 1325, 1320, 1352,
+ /*   210 */  1352, 1343, 1380, 1353, 1397, 1351, 1339, 1334, 1319, 1341,
+ /*   220 */  1303, 1364, 1359, 1368, 1362, 1366, 1360, 1350, 1354, 1318,
+ /*   230 */  1313, 1307, 1305, 1363, 1328, 1324, 1372, 1278, 1361, 1358,
+ /*   240 */  1277, 1276, 1356, 1296, 1322, 1309, 1317, 1315, 1314, 1312,
+ /*   250 */  1345, 1347, 1302, 1292, 1311, 1304, 1293, 1337, 1335, 1252,
+ /*   260 */  1248, 1332, 1330, 1329, 1327, 1326, 1323, 1321, 1297, 1301,
+ /*   270 */  1295, 1294, 1290, 1243, 1240, 1284, 1291, 1286, 1283, 1274,
+ /*   280 */  1281, 1271, 1238, 1241, 1236, 1235, 1227, 1226, 1267, 1266,
+ /*   290 */  1189, 1229, 1223, 1211, 1206, 1201, 1197, 1239, 1237, 1219,
+ /*   300 */  1216, 1209, 1208, 1185, 1089, 1086, 1087, 1137, 1136, 1164,
 };
 static const YYACTIONTYPE yy_default[] = {
- /*     0 */   632,  866,  954,  954,  866,  866,  954,  954,  954,  756,
- /*    10 */   954,  954,  954,  864,  954,  954,  784,  784,  928,  954,
- /*    20 */   954,  954,  954,  954,  954,  954,  954,  954,  954,  954,
- /*    30 */   954,  954,  954,  954,  954,  954,  954,  954,  954,  954,
- /*    40 */   954,  954,  954,  954,  954,  954,  954,  954,  954,  954,
- /*    50 */   954,  954,  954,  954,  954,  954,  954,  954,  954,  954,
- /*    60 */   954,  954,  954,  954,  954,  954,  954,  671,  760,  790,
- /*    70 */   954,  954,  954,  954,  954,  954,  954,  954,  927,  929,
- /*    80 */   798,  797,  907,  771,  795,  788,  792,  867,  860,  861,
- /*    90 */   859,  863,  868,  954,  791,  827,  844,  826,  838,  843,
- /*   100 */   850,  842,  839,  829,  828,  830,  831,  954,  954,  954,
- /*   110 */   954,  954,  954,  954,  954,  954,  954,  954,  954,  954,
- /*   120 */   954,  954,  954,  658,  725,  954,  954,  954,  954,  954,
- /*   130 */   954,  954,  954,  832,  833,  847,  846,  845,  954,  663,
- /*   140 */   954,  954,  954,  954,  954,  954,  954,  954,  954,  954,
- /*   150 */   934,  932,  954,  879,  954,  954,  954,  954,  954,  954,
- /*   160 */   954,  954,  954,  954,  954,  954,  954,  954,  954,  954,
- /*   170 */   954,  954,  954,  954,  954,  954,  954,  954,  954,  954,
- /*   180 */   638,  756,  756,  756,  632,  954,  954,  954,  946,  760,
- /*   190 */   750,  954,  954,  954,  954,  954,  954,  954,  954,  954,
- /*   200 */   954,  954,  954,  800,  739,  917,  919,  954,  900,  737,
- /*   210 */   660,  758,  673,  748,  640,  794,  773,  773,  912,  794,
- /*   220 */   912,  696,  719,  954,  784,  954,  784,  693,  784,  773,
- /*   230 */   862,  954,  954,  954,  757,  748,  954,  939,  764,  764,
- /*   240 */   931,  931,  764,  806,  729,  794,  736,  736,  736,  736,
- /*   250 */   764,  655,  794,  806,  729,  729,  764,  655,  906,  904,
- /*   260 */   764,  764,  655,  764,  655,  764,  655,  872,  727,  727,
- /*   270 */   727,  711,  876,  876,  872,  727,  696,  727,  711,  727,
- /*   280 */   727,  777,  772,  777,  772,  777,  772,  764,  764,  954,
- /*   290 */   789,  778,  787,  785,  794,  954,  714,  648,  648,  637,
- /*   300 */   637,  637,  637,  951,  951,  946,  698,  698,  681,  954,
- /*   310 */   954,  954,  954,  954,  954,  954,  881,  954,  954,  954,
- /*   320 */   954,  954,  954,  954,  954,  954,  954,  954,  954,  633,
- /*   330 */   941,  954,  954,  938,  954,  954,  954,  954,  799,  954,
- /*   340 */   954,  954,  954,  954,  954,  954,  954,  954,  954,  916,
- /*   350 */   954,  954,  954,  954,  954,  954,  954,  910,  954,  954,
- /*   360 */   954,  954,  954,  954,  903,  902,  954,  954,  954,  954,
- /*   370 */   954,  954,  954,  954,  954,  954,  954,  954,  954,  954,
- /*   380 */   954,  954,  954,  954,  954,  954,  954,  954,  954,  954,
- /*   390 */   954,  954,  786,  954,  779,  954,  865,  954,  954,  954,
- /*   400 */   954,  954,  954,  954,  954,  954,  954,  742,  815,  954,
- /*   410 */   814,  818,  813,  665,  954,  646,  954,  629,  634,  950,
- /*   420 */   953,  952,  949,  948,  947,  942,  940,  937,  936,  935,
- /*   430 */   933,  930,  926,  885,  883,  890,  889,  888,  887,  886,
- /*   440 */   884,  882,  880,  801,  796,  793,  925,  878,  738,  735,
- /*   450 */   734,  654,  943,  909,  918,  805,  804,  807,  915,  914,
- /*   460 */   913,  911,  908,  895,  803,  802,  730,  870,  869,  657,
- /*   470 */   899,  898,  897,  901,  905,  896,  766,  656,  653,  662,
- /*   480 */   717,  718,  726,  724,  723,  722,  721,  720,  716,  664,
- /*   490 */   672,  710,  695,  694,  875,  877,  874,  873,  703,  702,
- /*   500 */   708,  707,  706,  705,  704,  701,  700,  699,  692,  691,
- /*   510 */   697,  690,  713,  712,  709,  689,  733,  732,  731,  728,
- /*   520 */   688,  687,  686,  818,  685,  684,  824,  823,  811,  854,
- /*   530 */   753,  752,  751,  763,  762,  775,  774,  809,  808,  776,
- /*   540 */   761,  755,  754,  770,  769,  768,  767,  759,  749,  781,
- /*   550 */   783,  782,  780,  856,  765,  853,  924,  923,  922,  921,
- /*   560 */   920,  858,  857,  825,  822,  676,  677,  893,  892,  894,
- /*   570 */   891,  679,  678,  675,  674,  855,  744,  743,  851,  848,
- /*   580 */   840,  836,  852,  849,  841,  837,  835,  834,  820,  819,
- /*   590 */   817,  816,  812,  821,  667,  745,  741,  740,  810,  747,
- /*   600 */   746,  683,  682,  680,  661,  659,  652,  650,  649,  651,
- /*   610 */   647,  645,  644,  643,  642,  641,  670,  669,  668,  666,
- /*   620 */   665,  639,  636,  635,  631,  630,  628,
+ /*     0 */   633,  867,  955,  955,  867,  867,  955,  955,  955,  757,
+ /*    10 */   955,  955,  955,  865,  955,  955,  785,  785,  929,  955,
+ /*    20 */   955,  955,  955,  955,  955,  955,  955,  955,  955,  955,
+ /*    30 */   955,  955,  955,  955,  955,  955,  955,  955,  955,  955,
+ /*    40 */   955,  955,  955,  955,  955,  955,  955,  955,  955,  955,
+ /*    50 */   955,  955,  955,  955,  955,  955,  955,  955,  955,  955,
+ /*    60 */   955,  955,  955,  955,  955,  955,  955,  672,  761,  791,
+ /*    70 */   955,  955,  955,  955,  955,  955,  955,  955,  928,  930,
+ /*    80 */   799,  798,  908,  772,  796,  789,  793,  868,  861,  862,
+ /*    90 */   860,  864,  869,  955,  792,  828,  845,  827,  839,  844,
+ /*   100 */   851,  843,  840,  830,  829,  831,  832,  955,  955,  955,
+ /*   110 */   955,  955,  955,  955,  955,  955,  955,  955,  955,  955,
+ /*   120 */   955,  955,  955,  659,  726,  955,  955,  955,  955,  955,
+ /*   130 */   955,  955,  955,  833,  834,  848,  847,  846,  955,  664,
+ /*   140 */   955,  955,  955,  955,  955,  955,  955,  955,  955,  955,
+ /*   150 */   935,  933,  955,  880,  955,  955,  955,  955,  955,  955,
+ /*   160 */   955,  955,  955,  955,  955,  955,  955,  955,  955,  955,
+ /*   170 */   955,  955,  955,  955,  955,  955,  955,  955,  955,  955,
+ /*   180 */   639,  757,  757,  757,  633,  955,  955,  955,  947,  761,
+ /*   190 */   751,  955,  955,  955,  955,  955,  955,  955,  955,  955,
+ /*   200 */   955,  955,  955,  801,  740,  918,  920,  955,  901,  738,
+ /*   210 */   661,  759,  674,  749,  641,  795,  774,  774,  913,  795,
+ /*   220 */   913,  697,  720,  955,  785,  955,  785,  694,  785,  774,
+ /*   230 */   863,  955,  955,  955,  758,  749,  955,  940,  765,  765,
+ /*   240 */   932,  932,  765,  807,  730,  795,  737,  737,  737,  737,
+ /*   250 */   765,  656,  795,  807,  730,  730,  795,  765,  656,  907,
+ /*   260 */   905,  765,  765,  656,  765,  656,  765,  656,  873,  728,
+ /*   270 */   728,  728,  712,  877,  877,  873,  728,  697,  728,  712,
+ /*   280 */   728,  728,  778,  773,  778,  773,  778,  773,  765,  765,
+ /*   290 */   955,  790,  779,  788,  786,  795,  955,  715,  649,  649,
+ /*   300 */   638,  638,  638,  638,  952,  952,  947,  699,  699,  682,
+ /*   310 */   955,  955,  955,  955,  955,  955,  955,  882,  955,  955,
+ /*   320 */   955,  955,  955,  955,  955,  955,  955,  955,  955,  955,
+ /*   330 */   634,  942,  955,  955,  939,  955,  955,  955,  955,  800,
+ /*   340 */   955,  955,  955,  955,  955,  955,  955,  955,  955,  955,
+ /*   350 */   917,  955,  955,  955,  955,  955,  955,  955,  911,  955,
+ /*   360 */   955,  955,  955,  955,  955,  904,  903,  955,  955,  955,
+ /*   370 */   955,  955,  955,  955,  955,  955,  955,  955,  955,  955,
+ /*   380 */   955,  955,  955,  955,  955,  955,  955,  955,  955,  955,
+ /*   390 */   955,  955,  955,  787,  955,  780,  955,  866,  955,  955,
+ /*   400 */   955,  955,  955,  955,  955,  955,  955,  955,  743,  816,
+ /*   410 */   955,  815,  819,  814,  666,  955,  647,  955,  630,  635,
+ /*   420 */   951,  954,  953,  950,  949,  948,  943,  941,  938,  937,
+ /*   430 */   936,  934,  931,  927,  886,  884,  891,  890,  889,  888,
+ /*   440 */   887,  885,  883,  881,  802,  797,  794,  926,  879,  739,
+ /*   450 */   736,  735,  655,  944,  910,  919,  806,  805,  808,  916,
+ /*   460 */   915,  914,  912,  909,  896,  804,  803,  731,  871,  870,
+ /*   470 */   658,  900,  899,  898,  902,  906,  897,  767,  657,  654,
+ /*   480 */   663,  718,  719,  727,  725,  724,  723,  722,  721,  717,
+ /*   490 */   665,  673,  711,  696,  695,  876,  878,  875,  874,  704,
+ /*   500 */   703,  709,  708,  707,  706,  705,  702,  701,  700,  693,
+ /*   510 */   692,  698,  691,  714,  713,  710,  690,  734,  733,  732,
+ /*   520 */   729,  689,  688,  687,  819,  686,  685,  825,  824,  812,
+ /*   530 */   855,  754,  753,  752,  764,  763,  776,  775,  810,  809,
+ /*   540 */   777,  762,  756,  755,  771,  770,  769,  768,  760,  750,
+ /*   550 */   782,  784,  783,  781,  857,  766,  854,  925,  924,  923,
+ /*   560 */   922,  921,  859,  858,  826,  823,  677,  678,  894,  893,
+ /*   570 */   895,  892,  680,  679,  676,  675,  856,  745,  744,  852,
+ /*   580 */   849,  841,  837,  853,  850,  842,  838,  836,  835,  821,
+ /*   590 */   820,  818,  817,  813,  822,  668,  746,  742,  741,  811,
+ /*   600 */   748,  747,  684,  683,  681,  662,  660,  653,  651,  650,
+ /*   610 */   652,  648,  646,  645,  644,  643,  642,  671,  670,  669,
+ /*   620 */   667,  666,  640,  637,  636,  632,  631,  629,
 };
 
 /* The next table maps tokens into fallback tokens.  If a construct
@@ -111404,7 +112217,7 @@ static const char *const yyRuleName[] = {
  /* 239 */ "exprlist ::=",
  /* 240 */ "nexprlist ::= nexprlist COMMA expr",
  /* 241 */ "nexprlist ::= expr",
- /* 242 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP",
+ /* 242 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt",
  /* 243 */ "uniqueflag ::= UNIQUE",
  /* 244 */ "uniqueflag ::=",
  /* 245 */ "idxlist_opt ::=",
@@ -112123,7 +112936,7 @@ static const struct {
   { 220, 0 },
   { 215, 3 },
   { 215, 1 },
-  { 147, 11 },
+  { 147, 12 },
   { 227, 1 },
   { 227, 0 },
   { 178, 0 },
@@ -112565,6 +113378,7 @@ static void yy_reduce(
   if( yymsp[0].minor.yy159 ){
     yymsp[0].minor.yy159->op = (u8)yymsp[-1].minor.yy392;
     yymsp[0].minor.yy159->pPrior = yymsp[-2].minor.yy159;
+    if( yymsp[-1].minor.yy392!=TK_ALL ) pParse->hasCompound = 1;
   }else{
     sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy159);
   }
@@ -113127,11 +113941,11 @@ static void yy_reduce(
       case 241: /* nexprlist ::= expr */
 {yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy342.pExpr);}
         break;
-      case 242: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP */
+      case 242: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt */
 {
-  sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0, 
-                     sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy0,0), yymsp[-1].minor.yy442, 
yymsp[-9].minor.yy392,
-                      &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy392);
+  sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, 
+                     sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy442, 
yymsp[-10].minor.yy392,
+                      &yymsp[-11].minor.yy0, yymsp[0].minor.yy122, SQLITE_SO_ASC, yymsp[-8].minor.yy392);
 }
         break;
       case 243: /* uniqueflag ::= UNIQUE */
@@ -114057,7 +114871,6 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
     }
     case '-': {
       if( z[1]=='-' ){
-        /* IMP: R-50417-27976 -- syntax diagram for comments */
         for(i=2; (c=z[i])!=0 && c!='\n'; i++){}
         *tokenType = TK_SPACE;   /* IMP: R-22934-25134 */
         return i;
@@ -114090,7 +114903,6 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
         *tokenType = TK_SLASH;
         return 1;
       }
-      /* IMP: R-50417-27976 -- syntax diagram for comments */
       for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
       if( c ) i++;
       *tokenType = TK_SPACE;   /* IMP: R-22934-25134 */
@@ -114330,7 +115142,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
 
 
   mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
-  if( db->activeVdbeCnt==0 ){
+  if( db->nVdbeActive==0 ){
     db->u1.isInterrupted = 0;
   }
   pParse->rc = SQLITE_OK;
@@ -114952,6 +115764,9 @@ SQLITE_API char *sqlite3_data_directory = 0;
 SQLITE_API int sqlite3_initialize(void){
   MUTEX_LOGIC( sqlite3_mutex *pMaster; )       /* The main static mutex */
   int rc;                                      /* Result code */
+#ifdef SQLITE_EXTRA_INIT
+  int bRunExtraInit = 0;                       /* Extra initialization needed */
+#endif
 
 #ifdef SQLITE_OMIT_WSD
   rc = sqlite3_wsd_init(4096, 24);
@@ -115049,6 +115864,9 @@ SQLITE_API int sqlite3_initialize(void){
       sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, 
           sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage);
       sqlite3GlobalConfig.isInit = 1;
+#ifdef SQLITE_EXTRA_INIT
+      bRunExtraInit = 1;
+#endif
     }
     sqlite3GlobalConfig.inProgress = 0;
   }
@@ -115089,7 +115907,7 @@ SQLITE_API int sqlite3_initialize(void){
   ** compile-time option.
   */
 #ifdef SQLITE_EXTRA_INIT
-  if( rc==SQLITE_OK && sqlite3GlobalConfig.isInit ){
+  if( bRunExtraInit ){
     int SQLITE_EXTRA_INIT(const char*);
     rc = SQLITE_EXTRA_INIT(0);
   }
@@ -115277,8 +116095,8 @@ SQLITE_API int sqlite3_config(int op, ...){
         memset(&sqlite3GlobalConfig.m, 0, sizeof(sqlite3GlobalConfig.m));
       }else{
         /* The heap pointer is not NULL, then install one of the
-        ** mem5.c/mem3.c methods. If neither ENABLE_MEMSYS3 nor
-        ** ENABLE_MEMSYS5 is defined, return an error.
+        ** mem5.c/mem3.c methods.  The enclosing #if guarantees at
+        ** least one of these methods is currently enabled.
         */
 #ifdef SQLITE_ENABLE_MEMSYS3
         sqlite3GlobalConfig.m = *sqlite3MemGetMemsys3();
@@ -115297,7 +116115,7 @@ SQLITE_API int sqlite3_config(int op, ...){
       break;
     }
     
-    /* Record a pointer to the logger funcction and its first argument.
+    /* Record a pointer to the logger function and its first argument.
     ** The default is NULL.  Logging is disabled if the function pointer is
     ** NULL.
     */
@@ -115536,7 +116354,7 @@ static int binCollFunc(
 /*
 ** Another built-in collating sequence: NOCASE. 
 **
-** This collating sequence is intended to be used for "case independant
+** This collating sequence is intended to be used for "case independent
 ** comparison". SQLite's knowledge of upper and lower case equivalents
 ** extends only to the 26 characters used in the English language.
 **
@@ -115859,7 +116677,6 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){
         inTrans = 1;
       }
       sqlite3BtreeRollback(p, tripCode);
-      db->aDb[i].inTrans = 0;
     }
   }
   sqlite3VtabRollback(db);
@@ -115873,6 +116690,8 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){
 
   /* Any deferred constraint violations have now been resolved. */
   db->nDeferredCons = 0;
+  db->nDeferredImmCons = 0;
+  db->flags &= ~SQLITE_DeferFKs;
 
   /* If one has been configured, invoke the rollback-hook callback */
   if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
@@ -115899,6 +116718,7 @@ SQLITE_PRIVATE const char *sqlite3ErrName(int rc){
       case SQLITE_ABORT_ROLLBACK:     zName = "SQLITE_ABORT_ROLLBACK";    break;
       case SQLITE_BUSY:               zName = "SQLITE_BUSY";              break;
       case SQLITE_BUSY_RECOVERY:      zName = "SQLITE_BUSY_RECOVERY";     break;
+      case SQLITE_BUSY_SNAPSHOT:      zName = "SQLITE_BUSY_SNAPSHOT";     break;
       case SQLITE_LOCKED:             zName = "SQLITE_LOCKED";            break;
       case SQLITE_LOCKED_SHAREDCACHE: zName = "SQLITE_LOCKED_SHAREDCACHE";break;
       case SQLITE_NOMEM:              zName = "SQLITE_NOMEM";             break;
@@ -115933,6 +116753,7 @@ SQLITE_PRIVATE const char *sqlite3ErrName(int rc){
       case SQLITE_IOERR_SEEK:         zName = "SQLITE_IOERR_SEEK";        break;
       case SQLITE_IOERR_DELETE_NOENT: zName = "SQLITE_IOERR_DELETE_NOENT";break;
       case SQLITE_IOERR_MMAP:         zName = "SQLITE_IOERR_MMAP";        break;
+      case SQLITE_IOERR_GETTEMPPATH:  zName = "SQLITE_IOERR_GETTEMPPATH"; break;
       case SQLITE_CORRUPT:            zName = "SQLITE_CORRUPT";           break;
       case SQLITE_CORRUPT_VTAB:       zName = "SQLITE_CORRUPT_VTAB";      break;
       case SQLITE_NOTFOUND:           zName = "SQLITE_NOTFOUND";          break;
@@ -115972,6 +116793,7 @@ SQLITE_PRIVATE const char *sqlite3ErrName(int rc){
       case SQLITE_NOTICE_RECOVER_ROLLBACK:
                                 zName = "SQLITE_NOTICE_RECOVER_ROLLBACK"; break;
       case SQLITE_WARNING:            zName = "SQLITE_WARNING";           break;
+      case SQLITE_WARNING_AUTOINDEX:  zName = "SQLITE_WARNING_AUTOINDEX"; break;
       case SQLITE_DONE:               zName = "SQLITE_DONE";              break;
     }
   }
@@ -116132,7 +116954,7 @@ SQLITE_API void sqlite3_progress_handler(
   sqlite3_mutex_enter(db->mutex);
   if( nOps>0 ){
     db->xProgress = xProgress;
-    db->nProgressOps = nOps;
+    db->nProgressOps = (unsigned)nOps;
     db->pProgressArg = pArg;
   }else{
     db->xProgress = 0;
@@ -116230,7 +117052,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
   */
   p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0);
   if( p && p->iPrefEnc==enc && p->nArg==nArg ){
-    if( db->activeVdbeCnt ){
+    if( db->nVdbeActive ){
       sqlite3Error(db, SQLITE_BUSY, 
         "unable to delete/modify user-function due to active statements");
       assert( !db->mallocFailed );
@@ -116811,7 +117633,7 @@ static int createCollation(
   */
   pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0);
   if( pColl && pColl->xCmp ){
-    if( db->activeVdbeCnt ){
+    if( db->nVdbeActive ){
       sqlite3Error(db, SQLITE_BUSY, 
         "unable to delete/modify collation sequence due to active statements");
       return SQLITE_BUSY;
@@ -117009,20 +117831,20 @@ SQLITE_PRIVATE int sqlite3ParseUri(
     zFile = sqlite3_malloc(nByte);
     if( !zFile ) return SQLITE_NOMEM;
 
+    iIn = 5;
+#ifndef SQLITE_ALLOW_URI_AUTHORITY
     /* Discard the scheme and authority segments of the URI. */
     if( zUri[5]=='/' && zUri[6]=='/' ){
       iIn = 7;
       while( zUri[iIn] && zUri[iIn]!='/' ) iIn++;
-
       if( iIn!=7 && (iIn!=16 || memcmp("localhost", &zUri[7], 9)) ){
         *pzErrMsg = sqlite3_mprintf("invalid uri authority: %.*s", 
             iIn-7, &zUri[7]);
         rc = SQLITE_ERROR;
         goto parse_uri_out;
       }
-    }else{
-      iIn = 5;
     }
+#endif
 
     /* Copy the filename and any query parameters into the zFile buffer. 
     ** Decode %HH escape codes along the way. 
@@ -117286,7 +118108,10 @@ static int openDatabase(
   db->nextAutovac = -1;
   db->szMmap = sqlite3GlobalConfig.szMmap;
   db->nextPagesize = 0;
-  db->flags |= SQLITE_ShortColNames | SQLITE_AutoIndex | SQLITE_EnableTrigger
+  db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill
+#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
+                 | SQLITE_AutoIndex
+#endif
 #if SQLITE_DEFAULT_FILE_FORMAT<4
                  | SQLITE_LegacyFileFmt
 #endif
@@ -117626,8 +118451,6 @@ SQLITE_API int sqlite3_global_recover(void){
 ** mode.  Return TRUE if it is and FALSE if not.  Autocommit mode is on
 ** by default.  Autocommit is disabled by a BEGIN statement and reenabled
 ** by the next COMMIT or ROLLBACK.
-**
-******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
 */
 SQLITE_API int sqlite3_get_autocommit(sqlite3 *db){
   return db->autoCommit;
@@ -118830,7 +119653,7 @@ SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db){
 
 /* If not building as part of the core, include sqlite3ext.h. */
 #ifndef SQLITE_CORE
-SQLITE_API extern const sqlite3_api_routines *sqlite3_api;
+SQLITE_EXTENSION_INIT3
 #endif
 
 /************** Include fts3_tokenizer.h in the middle of fts3Int.h **********/
@@ -119117,6 +119940,18 @@ SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(const Fts3Hash *, const voi
 /************** Continuing where we left off in fts3Int.h ********************/
 
 /*
+** This constant determines the maximum depth of an FTS expression tree
+** that the library will create and use. FTS uses recursion to perform 
+** various operations on the query tree, so the disadvantage of a large
+** limit is that it may allow very large queries to use large amounts
+** of stack space (perhaps causing a stack overflow).
+*/
+#ifndef SQLITE_FTS3_MAX_EXPR_DEPTH
+# define SQLITE_FTS3_MAX_EXPR_DEPTH 12
+#endif
+
+
+/*
 ** This constant controls how often segments are merged. Once there are
 ** FTS3_MERGE_COUNT segments of level N, they are merged into a single
 ** segment of level N+1.
@@ -119271,6 +120106,7 @@ struct Fts3Table {
   const char *zName;              /* virtual table name */
   int nColumn;                    /* number of named columns in virtual table */
   char **azColumn;                /* column names.  malloced */
+  u8 *abNotindexed;               /* True for 'notindexed' columns */
   sqlite3_tokenizer *pTokenizer;  /* tokenizer for inserts and queries */
   char *zContentTbl;              /* content=xxx option, or NULL */
   char *zLanguageid;              /* languageid=xxx option, or NULL */
@@ -119498,7 +120334,6 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderPending(
   Fts3Table*,int,const char*,int,int,Fts3SegReader**);
 SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *);
 SQLITE_PRIVATE int sqlite3Fts3AllSegdirs(Fts3Table*, int, int, int, sqlite3_stmt **);
-SQLITE_PRIVATE int sqlite3Fts3ReadLock(Fts3Table *);
 SQLITE_PRIVATE int sqlite3Fts3ReadBlock(Fts3Table*, sqlite3_int64, char **, int*, int*);
 
 SQLITE_PRIVATE int sqlite3Fts3SelectDoctotal(Fts3Table *, sqlite3_stmt **);
@@ -120431,6 +121266,8 @@ static int fts3InitVtab(
   char *zUncompress = 0;          /* uncompress=? parameter (or NULL) */
   char *zContent = 0;             /* content=? parameter (or NULL) */
   char *zLanguageid = 0;          /* languageid=? parameter (or NULL) */
+  char **azNotindexed = 0;        /* The set of notindexed= columns */
+  int nNotindexed = 0;            /* Size of azNotindexed[] array */
 
   assert( strlen(argv[0])==4 );
   assert( (sqlite3_strnicmp(argv[0], "fts4", 4)==0 && isFts4)
@@ -120440,9 +121277,19 @@ static int fts3InitVtab(
   nDb = (int)strlen(argv[1]) + 1;
   nName = (int)strlen(argv[2]) + 1;
 
-  aCol = (const char **)sqlite3_malloc(sizeof(const char *) * (argc-2) );
-  if( !aCol ) return SQLITE_NOMEM;
-  memset((void *)aCol, 0, sizeof(const char *) * (argc-2));
+  nByte = sizeof(const char *) * (argc-2);
+  aCol = (const char **)sqlite3_malloc(nByte);
+  if( aCol ){
+    memset((void*)aCol, 0, nByte);
+    azNotindexed = (char **)sqlite3_malloc(nByte);
+  }
+  if( azNotindexed ){
+    memset(azNotindexed, 0, nByte);
+  }
+  if( !aCol || !azNotindexed ){
+    rc = SQLITE_NOMEM;
+    goto fts3_init_out;
+  }
 
   /* Loop through all of the arguments passed by the user to the FTS3/4
   ** module (i.e. all the column names and special arguments). This loop
@@ -120481,7 +121328,8 @@ static int fts3InitVtab(
         { "uncompress", 10 },     /* 3 -> UNCOMPRESS */
         { "order",       5 },     /* 4 -> ORDER */
         { "content",     7 },     /* 5 -> CONTENT */
-        { "languageid", 10 }      /* 6 -> LANGUAGEID */
+        { "languageid", 10 },     /* 6 -> LANGUAGEID */
+        { "notindexed", 10 }      /* 7 -> NOTINDEXED */
       };
 
       int iOpt;
@@ -120547,6 +121395,11 @@ static int fts3InitVtab(
               zLanguageid = zVal;
               zVal = 0;
               break;
+
+            case 7:              /* NOTINDEXED */
+              azNotindexed[nNotindexed++] = zVal;
+              zVal = 0;
+              break;
           }
         }
         sqlite3_free(zVal);
@@ -120618,6 +121471,7 @@ static int fts3InitVtab(
   nByte = sizeof(Fts3Table) +                  /* Fts3Table */
           nCol * sizeof(char *) +              /* azColumn */
           nIndex * sizeof(struct Fts3Index) +  /* aIndex */
+          nCol * sizeof(u8) +                  /* abNotindexed */
           nName +                              /* zName */
           nDb +                                /* zDb */
           nString;                             /* Space for azColumn strings */
@@ -120651,9 +121505,10 @@ static int fts3InitVtab(
   for(i=0; i<nIndex; i++){
     fts3HashInit(&p->aIndex[i].hPending, FTS3_HASH_STRING, 1);
   }
+  p->abNotindexed = (u8 *)&p->aIndex[nIndex];
 
   /* Fill in the zName and zDb fields of the vtab structure. */
-  zCsr = (char *)&p->aIndex[nIndex];
+  zCsr = (char *)&p->abNotindexed[nCol];
   p->zName = zCsr;
   memcpy(zCsr, argv[2], nName);
   zCsr += nName;
@@ -120674,7 +121529,26 @@ static int fts3InitVtab(
     assert( zCsr <= &((char *)p)[nByte] );
   }
 
-  if( (zCompress==0)!=(zUncompress==0) ){
+  /* Fill in the abNotindexed array */
+  for(iCol=0; iCol<nCol; iCol++){
+    int n = (int)strlen(p->azColumn[iCol]);
+    for(i=0; i<nNotindexed; i++){
+      char *zNot = azNotindexed[i];
+      if( zNot && 0==sqlite3_strnicmp(p->azColumn[iCol], zNot, n) ){
+        p->abNotindexed[iCol] = 1;
+        sqlite3_free(zNot);
+        azNotindexed[i] = 0;
+      }
+    }
+  }
+  for(i=0; i<nNotindexed; i++){
+    if( azNotindexed[i] ){
+      *pzErr = sqlite3_mprintf("no such column: %s", azNotindexed[i]);
+      rc = SQLITE_ERROR;
+    }
+  }
+
+  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);
@@ -120715,7 +121589,9 @@ fts3_init_out:
   sqlite3_free(zUncompress);
   sqlite3_free(zContent);
   sqlite3_free(zLanguageid);
+  for(i=0; i<nNotindexed; i++) sqlite3_free(azNotindexed[i]);
   sqlite3_free((void *)aCol);
+  sqlite3_free((void *)azNotindexed);
   if( rc!=SQLITE_OK ){
     if( p ){
       fts3DisconnectMethod((sqlite3_vtab *)p);
@@ -120773,7 +121649,7 @@ static int fts3BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
   ** strategy is possible.
   */
   pInfo->idxNum = FTS3_FULLSCAN_SEARCH;
-  pInfo->estimatedCost = 500000;
+  pInfo->estimatedCost = 5000000;
   for(i=0; i<pInfo->nConstraint; i++){
     struct sqlite3_index_constraint *pCons = &pInfo->aConstraint[i];
     if( pCons->usable==0 ) continue;
@@ -122334,11 +123210,7 @@ static int fts3FilterMethod(
       return rc;
     }
 
-    rc = sqlite3Fts3ReadLock(p);
-    if( rc!=SQLITE_OK ) return rc;
-
     rc = fts3EvalStart(pCsr);
-
     sqlite3Fts3SegmentsClose(p);
     if( rc!=SQLITE_OK ) return rc;
     pCsr->pNextId = pCsr->aDoclist;
@@ -124689,7 +125561,10 @@ SQLITE_PRIVATE int sqlite3Fts3Corrupt(){
 /*
 ** Initialize API pointer table, if required.
 */
-SQLITE_API int sqlite3_extension_init(
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+SQLITE_API int sqlite3_fts3_init(
   sqlite3 *db, 
   char **pzErrMsg,
   const sqlite3_api_routines *pApi
@@ -126193,17 +127068,16 @@ SQLITE_PRIVATE int sqlite3Fts3ExprParse(
   Fts3Expr **ppExpr,                  /* OUT: Parsed query structure */
   char **pzErr                        /* OUT: Error message (sqlite3_malloc) */
 ){
-  static const int MAX_EXPR_DEPTH = 12;
   int rc = fts3ExprParseUnbalanced(
       pTokenizer, iLangid, azCol, bFts4, nCol, iDefaultCol, z, n, ppExpr
   );
   
   /* Rebalance the expression. And check that its depth does not exceed
-  ** MAX_EXPR_DEPTH.  */
+  ** SQLITE_FTS3_MAX_EXPR_DEPTH.  */
   if( rc==SQLITE_OK && *ppExpr ){
-    rc = fts3ExprBalance(ppExpr, MAX_EXPR_DEPTH);
+    rc = fts3ExprBalance(ppExpr, SQLITE_FTS3_MAX_EXPR_DEPTH);
     if( rc==SQLITE_OK ){
-      rc = fts3ExprCheckDepth(*ppExpr, MAX_EXPR_DEPTH);
+      rc = fts3ExprCheckDepth(*ppExpr, SQLITE_FTS3_MAX_EXPR_DEPTH);
     }
   }
 
@@ -126212,7 +127086,8 @@ SQLITE_PRIVATE int sqlite3Fts3ExprParse(
     *ppExpr = 0;
     if( rc==SQLITE_TOOBIG ){
       *pzErr = sqlite3_mprintf(
-          "FTS expression tree is too large (maximum depth %d)", MAX_EXPR_DEPTH
+          "FTS expression tree is too large (maximum depth %d)", 
+          SQLITE_FTS3_MAX_EXPR_DEPTH
       );
       rc = SQLITE_ERROR;
     }else if( rc==SQLITE_ERROR ){
@@ -127707,7 +128582,7 @@ SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(
 
 #ifdef SQLITE_TEST
 
-/* #include <tcl.h> */
+#include <tcl.h>
 /* #include <string.h> */
 
 /*
@@ -129174,37 +130049,30 @@ static void fts3SqlExec(
 
 
 /*
-** This function ensures that the caller has obtained a shared-cache
-** table-lock on the %_content table. This is required before reading
-** data from the fts3 table. If this lock is not acquired first, then
-** the caller may end up holding read-locks on the %_segments and %_segdir
-** tables, but no read-lock on the %_content table. If this happens 
-** a second connection will be able to write to the fts3 table, but
-** attempting to commit those writes might return SQLITE_LOCKED or
-** SQLITE_LOCKED_SHAREDCACHE (because the commit attempts to obtain 
-** write-locks on the %_segments and %_segdir ** tables). 
+** This function ensures that the caller has obtained an exclusive 
+** shared-cache table-lock on the %_segdir table. This is required before 
+** writing data to the fts3 table. If this lock is not acquired first, then
+** the caller may end up attempting to take this lock as part of committing
+** a transaction, causing SQLite to return SQLITE_LOCKED or 
+** LOCKED_SHAREDCACHEto a COMMIT command.
 **
-** We try to avoid this because if FTS3 returns any error when committing
-** a transaction, the whole transaction will be rolled back. And this is
-** not what users expect when they get SQLITE_LOCKED_SHAREDCACHE. It can
-** still happen if the user reads data directly from the %_segments or
-** %_segdir tables instead of going through FTS3 though.
-**
-** This reasoning does not apply to a content=xxx table.
+** It is best to avoid this because if FTS3 returns any error when 
+** committing a transaction, the whole transaction will be rolled back. 
+** And this is not what users expect when they get SQLITE_LOCKED_SHAREDCACHE. 
+** It can still happen if the user locks the underlying tables directly 
+** instead of accessing them via FTS.
 */
-SQLITE_PRIVATE int sqlite3Fts3ReadLock(Fts3Table *p){
-  int rc;                         /* Return code */
-  sqlite3_stmt *pStmt;            /* Statement used to obtain lock */
-
-  if( p->zContentTbl==0 ){
-    rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pStmt, 0);
+static int fts3Writelock(Fts3Table *p){
+  int rc = SQLITE_OK;
+  
+  if( p->nPendingData==0 ){
+    sqlite3_stmt *pStmt;
+    rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_LEVEL, &pStmt, 0);
     if( rc==SQLITE_OK ){
       sqlite3_bind_null(pStmt, 1);
       sqlite3_step(pStmt);
       rc = sqlite3_reset(pStmt);
     }
-  }else{
-    rc = SQLITE_OK;
   }
 
   return rc;
@@ -129592,12 +130460,15 @@ static int fts3InsertTerms(
 ){
   int i;                          /* Iterator variable */
   for(i=2; i<p->nColumn+2; i++){
-    const char *zText = (const char *)sqlite3_value_text(apVal[i]);
-    int rc = fts3PendingTermsAdd(p, iLangid, zText, i-2, &aSz[i-2]);
-    if( rc!=SQLITE_OK ){
-      return rc;
+    int iCol = i-2;
+    if( p->abNotindexed[iCol]==0 ){
+      const char *zText = (const char *)sqlite3_value_text(apVal[i]);
+      int rc = fts3PendingTermsAdd(p, iLangid, zText, iCol, &aSz[iCol]);
+      if( rc!=SQLITE_OK ){
+        return rc;
+      }
+      aSz[p->nColumn] += sqlite3_value_bytes(apVal[i]);
     }
-    aSz[p->nColumn] += sqlite3_value_bytes(apVal[i]);
   }
   return SQLITE_OK;
 }
@@ -129744,9 +130615,12 @@ static void fts3DeleteTerms(
       int iLangid = langidFromSelect(p, pSelect);
       rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pSelect, 0));
       for(i=1; rc==SQLITE_OK && i<=p->nColumn; i++){
-        const char *zText = (const char *)sqlite3_column_text(pSelect, i);
-        rc = fts3PendingTermsAdd(p, iLangid, zText, -1, &aSz[i-1]);
-        aSz[p->nColumn] += sqlite3_column_bytes(pSelect, i);
+        int iCol = i-1;
+        if( p->abNotindexed[iCol]==0 ){
+          const char *zText = (const char *)sqlite3_column_text(pSelect, i);
+          rc = fts3PendingTermsAdd(p, iLangid, zText, -1, &aSz[iCol]);
+          aSz[p->nColumn] += sqlite3_column_bytes(pSelect, i);
+        }
       }
       if( rc!=SQLITE_OK ){
         sqlite3_reset(pSelect);
@@ -130147,7 +131021,7 @@ static int fts3SegReaderNextDocid(
       /* The following line of code (and the "p++" below the while() loop) is
       ** normally all that is required to move pointer p to the desired 
       ** position. The exception is if this node is being loaded from disk
-      ** incrementally and pointer "p" now points to the first byte passed
+      ** incrementally and pointer "p" now points to the first byte past
       ** the populated part of pReader->aNode[].
       */
       while( *p | c ) c = *p++ & 0x80;
@@ -131534,8 +132408,8 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderStep(
       fts3SegReaderSort(apSegment, nMerge, nMerge, xCmp);
       while( apSegment[0]->pOffsetList ){
         int j;                    /* Number of segments that share a docid */
-        char *pList;
-        int nList;
+        char *pList = 0;
+        int nList = 0;
         int nByte;
         sqlite3_int64 iDocid = apSegment[0]->iDocid;
         fts3SegReaderNextDocid(p, apSegment[0], &pList, &nList);
@@ -131988,9 +132862,11 @@ static int fts3DoRebuild(Fts3Table *p){
       rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pStmt, 0));
       memset(aSz, 0, sizeof(aSz[0]) * (p->nColumn+1));
       for(iCol=0; rc==SQLITE_OK && iCol<p->nColumn; iCol++){
-        const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1);
-        rc = fts3PendingTermsAdd(p, iLangid, z, iCol, &aSz[iCol]);
-        aSz[p->nColumn] += sqlite3_column_bytes(pStmt, iCol+1);
+        if( p->abNotindexed[iCol]==0 ){
+          const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1);
+          rc = fts3PendingTermsAdd(p, iLangid, z, iCol, &aSz[iCol]);
+          aSz[p->nColumn] += sqlite3_column_bytes(pStmt, iCol+1);
+        }
       }
       if( p->bHasDocsize ){
         fts3InsertDocsize(&rc, p, aSz);
@@ -133793,32 +134669,34 @@ SQLITE_PRIVATE int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *pCsr){
     iDocid = sqlite3_column_int64(pCsr->pStmt, 0);
   
     for(i=0; i<p->nColumn && rc==SQLITE_OK; i++){
-      const char *zText = (const char *)sqlite3_column_text(pCsr->pStmt, i+1);
-      sqlite3_tokenizer_cursor *pTC = 0;
-  
-      rc = sqlite3Fts3OpenTokenizer(pT, pCsr->iLangid, zText, -1, &pTC);
-      while( rc==SQLITE_OK ){
-        char const *zToken;       /* Buffer containing token */
-        int nToken = 0;           /* Number of bytes in token */
-        int iDum1 = 0, iDum2 = 0; /* Dummy variables */
-        int iPos = 0;             /* Position of token in zText */
-  
-        rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos);
-        for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){
-          Fts3PhraseToken *pPT = pDef->pToken;
-          if( (pDef->iCol>=p->nColumn || pDef->iCol==i)
-           && (pPT->bFirst==0 || iPos==0)
-           && (pPT->n==nToken || (pPT->isPrefix && pPT->n<nToken))
-           && (0==memcmp(zToken, pPT->z, pPT->n))
-          ){
-            fts3PendingListAppend(&pDef->pList, iDocid, i, iPos, &rc);
+      if( p->abNotindexed[i]==0 ){
+        const char *zText = (const char *)sqlite3_column_text(pCsr->pStmt, i+1);
+        sqlite3_tokenizer_cursor *pTC = 0;
+
+        rc = sqlite3Fts3OpenTokenizer(pT, pCsr->iLangid, zText, -1, &pTC);
+        while( rc==SQLITE_OK ){
+          char const *zToken;       /* Buffer containing token */
+          int nToken = 0;           /* Number of bytes in token */
+          int iDum1 = 0, iDum2 = 0; /* Dummy variables */
+          int iPos = 0;             /* Position of token in zText */
+
+          rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos);
+          for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){
+            Fts3PhraseToken *pPT = pDef->pToken;
+            if( (pDef->iCol>=p->nColumn || pDef->iCol==i)
+                && (pPT->bFirst==0 || iPos==0)
+                && (pPT->n==nToken || (pPT->isPrefix && pPT->n<nToken))
+                && (0==memcmp(zToken, pPT->z, pPT->n))
+              ){
+              fts3PendingListAppend(&pDef->pList, iDocid, i, iPos, &rc);
+            }
           }
         }
+        if( pTC ) pModule->xClose(pTC);
+        if( rc==SQLITE_DONE ) rc = SQLITE_OK;
       }
-      if( pTC ) pModule->xClose(pTC);
-      if( rc==SQLITE_DONE ) rc = SQLITE_OK;
     }
-  
+
     for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){
       if( pDef->pList ){
         rc = fts3PendingListAppendVarint(&pDef->pList, 0);
@@ -133982,6 +134860,9 @@ SQLITE_PRIVATE int sqlite3Fts3UpdateMethod(
   aSzIns = &aSzDel[p->nColumn+1];
   memset(aSzDel, 0, sizeof(aSzDel[0])*(p->nColumn+1)*2);
 
+  rc = fts3Writelock(p);
+  if( rc!=SQLITE_OK ) goto update_out;
+
   /* If this is an INSERT operation, or an UPDATE that modifies the rowid
   ** value, then this operation requires constraint handling.
   **
@@ -134601,6 +135482,7 @@ static int fts3StringAppend(
     pStr->z = zNew;
     pStr->nAlloc = nAlloc;
   }
+  assert( pStr->z!=0 && (pStr->nAlloc >= pStr->n+nAppend+1) );
 
   /* Append the data to the string buffer. */
   memcpy(&pStr->z[pStr->n], zAppend, nAppend);
@@ -136115,28 +136997,27 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int c){
     0x02A97004, 0x02A9DC03, 0x02A9EC01, 0x02AAC001, 0x02AAC803,
     0x02AADC02, 0x02AAF802, 0x02AB0401, 0x02AB7802, 0x02ABAC07,
     0x02ABD402, 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02,
-    0x037FFC02, 0x03E3FC01, 0x03EC7801, 0x03ECA401, 0x03EEC810,
-    0x03F4F802, 0x03F7F002, 0x03F8001A, 0x03F88007, 0x03F8C023,
-    0x03F95013, 0x03F9A004, 0x03FBFC01, 0x03FC040F, 0x03FC6807,
-    0x03FCEC06, 0x03FD6C0B, 0x03FF8007, 0x03FFA007, 0x03FFE405,
-    0x04040003, 0x0404DC09, 0x0405E411, 0x0406400C, 0x0407402E,
-    0x040E7C01, 0x040F4001, 0x04215C01, 0x04247C01, 0x0424FC01,
-    0x04280403, 0x04281402, 0x04283004, 0x0428E003, 0x0428FC01,
-    0x04294009, 0x0429FC01, 0x042CE407, 0x04400003, 0x0440E016,
-    0x04420003, 0x0442C012, 0x04440003, 0x04449C0E, 0x04450004,
-    0x04460003, 0x0446CC0E, 0x04471404, 0x045AAC0D, 0x0491C004,
-    0x05BD442E, 0x05BE3C04, 0x074000F6, 0x07440027, 0x0744A4B5,
-    0x07480046, 0x074C0057, 0x075B0401, 0x075B6C01, 0x075BEC01,
-    0x075C5401, 0x075CD401, 0x075D3C01, 0x075DBC01, 0x075E2401,
-    0x075EA401, 0x075F0C01, 0x07BBC002, 0x07C0002C, 0x07C0C064,
-    0x07C2800F, 0x07C2C40E, 0x07C3040F, 0x07C3440F, 0x07C4401F,
-    0x07C4C03C, 0x07C5C02B, 0x07C7981D, 0x07C8402B, 0x07C90009,
-    0x07C94002, 0x07CC0021, 0x07CCC006, 0x07CCDC46, 0x07CE0014,
-    0x07CE8025, 0x07CF1805, 0x07CF8011, 0x07D0003F, 0x07D10001,
-    0x07D108B6, 0x07D3E404, 0x07D4003E, 0x07D50004, 0x07D54018,
-    0x07D7EC46, 0x07D9140B, 0x07DA0046, 0x07DC0074, 0x38000401,
-    0x38008060, 0x380400F0, 0x3C000001, 0x3FFFF401, 0x40000001,
-    0x43FFF401,
+    0x037FFC01, 0x03EC7801, 0x03ECA401, 0x03EEC810, 0x03F4F802,
+    0x03F7F002, 0x03F8001A, 0x03F88007, 0x03F8C023, 0x03F95013,
+    0x03F9A004, 0x03FBFC01, 0x03FC040F, 0x03FC6807, 0x03FCEC06,
+    0x03FD6C0B, 0x03FF8007, 0x03FFA007, 0x03FFE405, 0x04040003,
+    0x0404DC09, 0x0405E411, 0x0406400C, 0x0407402E, 0x040E7C01,
+    0x040F4001, 0x04215C01, 0x04247C01, 0x0424FC01, 0x04280403,
+    0x04281402, 0x04283004, 0x0428E003, 0x0428FC01, 0x04294009,
+    0x0429FC01, 0x042CE407, 0x04400003, 0x0440E016, 0x04420003,
+    0x0442C012, 0x04440003, 0x04449C0E, 0x04450004, 0x04460003,
+    0x0446CC0E, 0x04471404, 0x045AAC0D, 0x0491C004, 0x05BD442E,
+    0x05BE3C04, 0x074000F6, 0x07440027, 0x0744A4B5, 0x07480046,
+    0x074C0057, 0x075B0401, 0x075B6C01, 0x075BEC01, 0x075C5401,
+    0x075CD401, 0x075D3C01, 0x075DBC01, 0x075E2401, 0x075EA401,
+    0x075F0C01, 0x07BBC002, 0x07C0002C, 0x07C0C064, 0x07C2800F,
+    0x07C2C40E, 0x07C3040F, 0x07C3440F, 0x07C4401F, 0x07C4C03C,
+    0x07C5C02B, 0x07C7981D, 0x07C8402B, 0x07C90009, 0x07C94002,
+    0x07CC0021, 0x07CCC006, 0x07CCDC46, 0x07CE0014, 0x07CE8025,
+    0x07CF1805, 0x07CF8011, 0x07D0003F, 0x07D10001, 0x07D108B6,
+    0x07D3E404, 0x07D4003E, 0x07D50004, 0x07D54018, 0x07D7EC46,
+    0x07D9140B, 0x07DA0046, 0x07DC0074, 0x38000401, 0x38008060,
+    0x380400F0,
   };
   static const unsigned int aAscii[4] = {
     0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
@@ -139731,7 +140612,10 @@ SQLITE_API int sqlite3_rtree_geometry_callback(
 }
 
 #if !SQLITE_CORE
-SQLITE_API int sqlite3_extension_init(
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+SQLITE_API int sqlite3_rtree_init(
   sqlite3 *db,
   char **pzErrMsg,
   const sqlite3_api_routines *pApi
@@ -139769,7 +140653,7 @@ SQLITE_API int sqlite3_extension_init(
 **   * Implementations of the SQL scalar upper() and lower() functions
 **     for case mapping.
 **
-**   * Integration of ICU and SQLite collation seqences.
+**   * Integration of ICU and SQLite collation sequences.
 **
 **   * An implementation of the LIKE operator that uses ICU to 
 **     provide case-independent matching.
@@ -140233,7 +141117,10 @@ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){
 }
 
 #if !SQLITE_CORE
-SQLITE_API int sqlite3_extension_init(
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+SQLITE_API int sqlite3_icu_init(
   sqlite3 *db, 
   char **pzErrMsg,
   const sqlite3_api_routines *pApi
diff --git a/libgda/sqlite/sqlite-src/sqlite3.h b/libgda/sqlite/sqlite-src/sqlite3.h
index e398838..70cfd5f 100644
--- a/libgda/sqlite/sqlite-src/sqlite3.h
+++ b/libgda/sqlite/sqlite-src/sqlite3.h
@@ -107,9 +107,9 @@ extern "C" {
 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
 ** [sqlite_version()] and [sqlite_source_id()].
 */
-#define SQLITE_VERSION        "3.7.17"
-#define SQLITE_VERSION_NUMBER 3007017
-#define SQLITE_SOURCE_ID      "2013-05-20 00:56:22 118a3b35693b134d56ebd780123b7fd6f1497668"
+#define SQLITE_VERSION        "3.8.0.2"
+#define SQLITE_VERSION_NUMBER 3008000
+#define SQLITE_SOURCE_ID      "2013-09-03 17:11:13 7dd4968f235d6e1ca9547cda9cf3bd570e1609ef"
 
 /*
 ** CAPI3REF: Run-Time Library Version Numbers
@@ -478,8 +478,10 @@ SQLITE_API int sqlite3_exec(
 #define SQLITE_IOERR_SEEK              (SQLITE_IOERR | (22<<8))
 #define SQLITE_IOERR_DELETE_NOENT      (SQLITE_IOERR | (23<<8))
 #define SQLITE_IOERR_MMAP              (SQLITE_IOERR | (24<<8))
+#define SQLITE_IOERR_GETTEMPPATH       (SQLITE_IOERR | (25<<8))
 #define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
 #define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
+#define SQLITE_BUSY_SNAPSHOT           (SQLITE_BUSY   |  (2<<8))
 #define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
 #define SQLITE_CANTOPEN_ISDIR          (SQLITE_CANTOPEN | (2<<8))
 #define SQLITE_CANTOPEN_FULLPATH       (SQLITE_CANTOPEN | (3<<8))
@@ -499,6 +501,7 @@ SQLITE_API int sqlite3_exec(
 #define SQLITE_CONSTRAINT_VTAB         (SQLITE_CONSTRAINT | (9<<8))
 #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))
 
 /*
 ** CAPI3REF: Flags For File Open Operations
@@ -2557,9 +2560,10 @@ SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
 ** interface is to keep a GUI updated during a large query.
 **
 ** ^The parameter P is passed through as the only parameter to the 
-** callback function X.  ^The parameter N is the number of 
+** callback function X.  ^The parameter N is the approximate number of 
 ** [virtual machine instructions] that are evaluated between successive
-** invocations of the callback X.
+** invocations of the callback X.  ^If N is less than one then the progress
+** handler is disabled.
 **
 ** ^Only a single progress handler may be defined at one time per
 ** [database connection]; setting a new progress handler cancels the
@@ -4179,41 +4183,49 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
 /*
 ** CAPI3REF: Function Auxiliary Data
 **
-** The following two functions may be used by scalar SQL functions to
+** These functions may be used by (non-aggregate) SQL functions to
 ** associate metadata with argument values. If the same value is passed to
 ** multiple invocations of the same SQL function during query execution, under
-** some circumstances the associated metadata may be preserved. This may
-** be used, for example, to add a regular-expression matching scalar
-** function. The compiled version of the regular expression is stored as
-** metadata associated with the SQL value passed as the regular expression
-** pattern.  The compiled regular expression can be reused on multiple
-** invocations of the same function so that the original pattern string
-** does not need to be recompiled on each invocation.
+** some circumstances the associated metadata may be preserved.  An example
+** of where this might be useful is in a regular-expression matching
+** function. The compiled version of the regular expression can be stored as
+** metadata associated with the pattern string.  
+** Then as long as the pattern string remains the same,
+** the compiled regular expression can be reused on multiple
+** invocations of the same function.
 **
 ** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
 ** associated by the sqlite3_set_auxdata() function with the Nth argument
-** value to the application-defined function. ^If no metadata has been ever
-** been set for the Nth argument of the function, or if the corresponding
-** function parameter has changed since the meta-data was set,
-** then sqlite3_get_auxdata() returns a NULL pointer.
-**
-** ^The sqlite3_set_auxdata() interface saves the metadata
-** pointed to by its 3rd parameter as the metadata for the N-th
-** argument of the application-defined function.  Subsequent
-** calls to sqlite3_get_auxdata() might return this data, if it has
-** not been destroyed.
-** ^If it is not NULL, SQLite will invoke the destructor
-** function given by the 4th parameter to sqlite3_set_auxdata() on
-** the metadata when the corresponding function parameter changes
-** or when the SQL statement completes, whichever comes first.
-**
-** SQLite is free to call the destructor and drop metadata on any
-** parameter of any function at any time.  ^The only guarantee is that
-** the destructor will be called before the metadata is dropped.
+** value to the application-defined function. ^If there is no metadata
+** associated with the function argument, this sqlite3_get_auxdata() interface
+** returns a NULL pointer.
+**
+** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
+** argument of the application-defined function.  ^Subsequent
+** calls to sqlite3_get_auxdata(C,N) return P from the most recent
+** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or
+** NULL if the metadata has been discarded.
+** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL,
+** SQLite will invoke the destructor function X with parameter P exactly
+** once, when the metadata is discarded.
+** SQLite is free to discard the metadata at any time, including: <ul>
+** <li> when the corresponding function parameter changes, or
+** <li> when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
+**      SQL statement, or
+** <li> when sqlite3_set_auxdata() is invoked again on the same parameter, or
+** <li> during the original sqlite3_set_auxdata() call when a memory 
+**      allocation error occurs. </ul>)^
+**
+** Note the last bullet in particular.  The destructor X in 
+** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
+** sqlite3_set_auxdata() interface even returns.  Hence sqlite3_set_auxdata()
+** should be called near the end of the function implementation and the
+** function implementation should not make any use of P after
+** sqlite3_set_auxdata() has been called.
 **
 ** ^(In practice, metadata is preserved between function calls for
-** expressions that are constant at compile time. This includes literal
-** values and [parameters].)^
+** function parameters that are compile-time constants, including literal
+** values and [parameters] and expressions composed from the same.)^
 **
 ** These routines must be called from the same thread in which
 ** the SQL function is running.
@@ -4518,6 +4530,11 @@ SQLITE_API int sqlite3_key(
   sqlite3 *db,                   /* Database to be rekeyed */
   const void *pKey, int nKey     /* The key */
 );
+SQLITE_API int sqlite3_key_v2(
+  sqlite3 *db,                   /* Database to be rekeyed */
+  const char *zDbName,           /* Name of the database */
+  const void *pKey, int nKey     /* The key */
+);
 
 /*
 ** Change the key on an open database.  If the current database is not
@@ -4531,6 +4548,11 @@ SQLITE_API int sqlite3_rekey(
   sqlite3 *db,                   /* Database to be rekeyed */
   const void *pKey, int nKey     /* The new key */
 );
+SQLITE_API int sqlite3_rekey_v2(
+  sqlite3 *db,                   /* Database to be rekeyed */
+  const char *zDbName,           /* Name of the database */
+  const void *pKey, int nKey     /* The new key */
+);
 
 /*
 ** Specify the activation key for a SEE database.  Unless 
@@ -5116,11 +5138,24 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
 ** on the list of automatic extensions is a harmless no-op. ^No entry point
 ** will be called more than once for each database connection that is opened.
 **
-** See also: [sqlite3_reset_auto_extension()].
+** See also: [sqlite3_reset_auto_extension()]
+** and [sqlite3_cancel_auto_extension()]
 */
 SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
 
 /*
+** CAPI3REF: Cancel Automatic Extension Loading
+**
+** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the
+** initialization routine X that was registered using a prior call to
+** [sqlite3_auto_extension(X)].  ^The [sqlite3_cancel_auto_extension(X)]
+** routine returns 1 if initialization routine X was successfully 
+** 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));
+
+/*
 ** CAPI3REF: Reset Automatic Extension Loading
 **
 ** ^This interface disables all automatic extensions previously
@@ -6232,6 +6267,12 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
 ** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
 ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
 ** </dd>
+**
+** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
+** <dd>This parameter returns zero for the current value if and only if
+** all foreign key constraints (deferred or immediate) have been
+** resolved.)^  ^The highwater mark is always 0.
+** </dd>
 ** </dl>
 */
 #define SQLITE_DBSTATUS_LOOKASIDE_USED       0
@@ -6244,7 +6285,8 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
 #define SQLITE_DBSTATUS_CACHE_HIT            7
 #define SQLITE_DBSTATUS_CACHE_MISS           8
 #define SQLITE_DBSTATUS_CACHE_WRITE          9
-#define SQLITE_DBSTATUS_MAX                  9   /* Largest defined DBSTATUS */
+#define SQLITE_DBSTATUS_DEFERRED_FKS        10
+#define SQLITE_DBSTATUS_MAX                 10   /* Largest defined DBSTATUS */
 
 
 /*
@@ -6298,11 +6340,21 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
 ** A non-zero value in this counter may indicate an opportunity to
 ** improvement performance by adding permanent indices that do not
 ** need to be reinitialized each time the statement is run.</dd>
+**
+** [[SQLITE_STMTSTATUS_VM_STEP]] <dt>SQLITE_STMTSTATUS_VM_STEP</dt>
+** <dd>^This is the number of virtual machine operations executed
+** by the prepared statement if that number is less than or equal
+** to 2147483647.  The number of virtual machine operations can be 
+** used as a proxy for the total work done by the prepared statement.
+** If the number of virtual machine operations exceeds 2147483647
+** then the value returned by this statement status code is undefined.
+** </dd>
 ** </dl>
 */
 #define SQLITE_STMTSTATUS_FULLSCAN_STEP     1
 #define SQLITE_STMTSTATUS_SORT              2
 #define SQLITE_STMTSTATUS_AUTOINDEX         3
+#define SQLITE_STMTSTATUS_VM_STEP           4
 
 /*
 ** CAPI3REF: Custom Page Cache Object
@@ -7181,7 +7233,7 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
 #ifdef __cplusplus
 }  /* End of the 'extern "C"' block */
 #endif
-#endif
+#endif /* _SQLITE3_H_ */
 
 /*
 ** 2010 August 30
diff --git a/providers/sqlcipher/sqlcipher.patch b/providers/sqlcipher/sqlcipher.patch
index fad792e..5f0f8d5 100644
--- a/providers/sqlcipher/sqlcipher.patch
+++ b/providers/sqlcipher/sqlcipher.patch
@@ -1,6 +1,6 @@
---- sqlite3.c.sqlite   2013-07-13 11:02:55.228615268 +0200
-+++ sqlite3.c  2013-07-13 11:02:46.604615238 +0200
-@@ -12585,9 +12585,45 @@
+--- sqlite3.c.sqlite   2013-11-09 12:42:08.623520057 +0100
++++ sqlite3.c  2013-11-09 12:41:58.695520274 +0100
+@@ -12566,9 +12566,45 @@
  #endif /* _SQLITEINT_H_ */
  
  /************** End of sqliteInt.h *******************************************/
@@ -48,7 +48,7 @@
  **
  ** The author disclaims copyright to this source code.  In place of
  ** a legal notice, here is a blessing:
-@@ -12597,3032 +12633,3229 @@
+@@ -12578,246 +12614,3589 @@
  **    May you share freely, never taking more than you give.
  **
  *************************************************************************
@@ -585,9 +585,6 @@
 +** 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 */
@@ -602,109 +599,18 @@
 +  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
- 
--#ifdef SQLITE_32BIT_ROWID
--  "32BIT_ROWID",
--#endif
--#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC
--  "4_BYTE_ALIGNED_MALLOC",
--#endif
--#ifdef SQLITE_CASE_SENSITIVE_LIKE
--  "CASE_SENSITIVE_LIKE",
--#endif
--#ifdef SQLITE_CHECK_PAGES
--  "CHECK_PAGES",
--#endif
--#ifdef SQLITE_COVERAGE_TEST
--  "COVERAGE_TEST",
--#endif
--#ifdef SQLITE_DEBUG
--  "DEBUG",
--#endif
--#ifdef 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
--  "DISABLE_DIRSYNC",
--#endif
--#ifdef SQLITE_DISABLE_LFS
--  "DISABLE_LFS",
--#endif
--#ifdef SQLITE_ENABLE_ATOMIC_WRITE
--  "ENABLE_ATOMIC_WRITE",
--#endif
--#ifdef SQLITE_ENABLE_CEROD
--  "ENABLE_CEROD",
--#endif
--#ifdef SQLITE_ENABLE_COLUMN_METADATA
--  "ENABLE_COLUMN_METADATA",
--#endif
--#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
--  "ENABLE_EXPENSIVE_ASSERT",
--#endif
--#ifdef SQLITE_ENABLE_FTS1
--  "ENABLE_FTS1",
--#endif
--#ifdef SQLITE_ENABLE_FTS2
--  "ENABLE_FTS2",
--#endif
--#ifdef SQLITE_ENABLE_FTS3
--  "ENABLE_FTS3",
--#endif
--#ifdef SQLITE_ENABLE_FTS3_PARENTHESIS
--  "ENABLE_FTS3_PARENTHESIS",
--#endif
--#ifdef SQLITE_ENABLE_FTS4
--  "ENABLE_FTS4",
--#endif
--#ifdef SQLITE_ENABLE_ICU
--  "ENABLE_ICU",
--#endif
--#ifdef SQLITE_ENABLE_IOTRACE
--  "ENABLE_IOTRACE",
--#endif
--#ifdef SQLITE_ENABLE_LOAD_EXTENSION
--  "ENABLE_LOAD_EXTENSION",
--#endif
--#ifdef SQLITE_ENABLE_LOCKING_STYLE
--  "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE),
--#endif
--#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
--  "ENABLE_MEMORY_MANAGEMENT",
--#endif
--#ifdef SQLITE_ENABLE_MEMSYS3
--  "ENABLE_MEMSYS3",
--#endif
--#ifdef SQLITE_ENABLE_MEMSYS5
--  "ENABLE_MEMSYS5",
--#endif
--#ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK
--  "ENABLE_OVERSIZE_CELL_CHECK",
++
 +/*
 +** An instance of this object represents a single database file.
 +** 
@@ -750,9 +656,7 @@
 +  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
--#ifdef SQLITE_ENABLE_RTREE
--  "ENABLE_RTREE",
++#endif
 +  u8 inTransaction;     /* Transaction state */
 +  u8 max1bytePayload;   /* Maximum first byte of cell for a 1-byte payload */
 +  u16 btsFlags;         /* Boolean parameters.  See BTS_* macros below */
@@ -773,9 +677,7 @@
 +  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
--#ifdef SQLITE_ENABLE_STAT3
--  "ENABLE_STAT3",
++#endif
 +  u8 *pTmpSpace;        /* BtShared.pageSize bytes of space for tmp use */
 +};
 +
@@ -839,9 +741,7 @@
 +  struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */
 +#ifndef SQLITE_OMIT_INCRBLOB
 +  Pgno *aOverflow;          /* Cache of overflow page locations */
- #endif
--#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
--  "ENABLE_UNLOCK_NOTIFY",
++#endif
 +  Pgno pgnoRoot;            /* The root page of this tree */
 +  sqlite3_int64 cachedRowid; /* Next rowid cache.  0 means not valid */
 +  CellInfo info;            /* A parse of the cell we are pointing at */
@@ -854,9 +754,7 @@
 +  u8 eState;                /* One of the CURSOR_XXX constants (see below) */
 +#ifndef SQLITE_OMIT_INCRBLOB
 +  u8 isIncrblobHandle;      /* True if this cursor is an incr. io handle */
- #endif
--#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
--  "ENABLE_UPDATE_DELETE_LIMIT",
++#endif
 +  u8 hints;                             /* As configured by CursorSetHints() */
 +  i16 iPage;                            /* Index of current page in apPage */
 +  u16 aiIdx[BTCURSOR_MAX_DEPTH];        /* Current index in apPage[i] */
@@ -866,14 +764,19 @@
 +/*
 +** Potential values for BtCursor.eState.
 +**
-+** CURSOR_VALID:
-+**   Cursor points to a valid entry. getPayload() etc. may be called.
-+**
 +** CURSOR_INVALID:
 +**   Cursor does not point to a valid entry. This can happen (for example) 
 +**   because the table is empty or because BtreeCursorFirst() has not been
 +**   called.
 +**
++** CURSOR_VALID:
++**   Cursor points to a valid entry. getPayload() etc. may be called.
++**
++** CURSOR_SKIPNEXT:
++**   Cursor is valid except that the Cursor.skipNext field is non-zero
++**   indicating that the next sqlite3BtreeNext() or sqlite3BtreePrevious()
++**   operation should be a no-op.
++**
 +** CURSOR_REQUIRESEEK:
 +**   The table that this cursor was opened on still exists, but has been 
 +**   modified since the cursor was last used. The cursor position is saved
@@ -890,8 +793,9 @@
 +*/
 +#define CURSOR_INVALID           0
 +#define CURSOR_VALID             1
-+#define CURSOR_REQUIRESEEK       2
-+#define CURSOR_FAULT             3
++#define CURSOR_SKIPNEXT          2
++#define CURSOR_REQUIRESEEK       3
++#define CURSOR_FAULT             4
 +
 +/* 
 +** The database page the PENDING_BYTE occupies. This page is never used.
@@ -973,7 +877,7 @@
 +#define ISAUTOVACUUM (pBt->autoVacuum)
 +#else
 +#define ISAUTOVACUUM 0
- #endif
++#endif
 +
 +
 +/*
@@ -1043,26 +947,7 @@
 +**  
 +*/
 +/* BEGIN SQLCIPHER */
- #ifdef SQLITE_HAS_CODEC
--  "HAS_CODEC",
--#endif
--#ifdef SQLITE_HAVE_ISNAN
--  "HAVE_ISNAN",
--#endif
--#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
--  "HOMEGROWN_RECURSIVE_MUTEX",
--#endif
--#ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS
--  "IGNORE_AFP_LOCK_ERRORS",
--#endif
--#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
--  "IGNORE_FLOCK_LOCK_ERRORS",
--#endif
--#ifdef SQLITE_INT64_TYPE
--  "INT64_TYPE",
--#endif
--#ifdef SQLITE_LOCK_TRACE
--  "LOCK_TRACE",
++#ifdef SQLITE_HAS_CODEC
 +#ifndef CRYPTO_H
 +#define CRYPTO_H
 +
@@ -1070,23 +955,17 @@
 +   && !defined (SQLCIPHER_CRYPTO_LIBTOMCRYPT) \
 +   && !defined (SQLCIPHER_CRYPTO_OPENSSL)
 +#define SQLCIPHER_CRYPTO_OPENSSL
- #endif
--#if defined(SQLITE_MAX_MMAP_SIZE) && !defined(SQLITE_MAX_MMAP_SIZE_xc)
--  "MAX_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE),
++#endif
 +
 +#define FILE_HEADER_SZ 16
 +
 +#ifndef CIPHER_VERSION
-+#define CIPHER_VERSION "2.2.1"
- #endif
--#ifdef SQLITE_MAX_SCHEMA_RETRY
--  "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY),
++#define CIPHER_VERSION "3.0.0"
++#endif
 +
 +#ifndef CIPHER
 +#define CIPHER "aes-256-cbc"
- #endif
--#ifdef SQLITE_MEMDEBUG
--  "MEMDEBUG",
++#endif
 +
 +#define CIPHER_DECRYPT 0
 +#define CIPHER_ENCRYPT 1
@@ -1096,10 +975,8 @@
 +#define CIPHER_READWRITE_CTX 2
 +
 +#ifndef PBKDF2_ITER
-+#define PBKDF2_ITER 4000
- #endif
--#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
--  "MIXED_ENDIAN_64BIT_FLOAT",
++#define PBKDF2_ITER 64000
++#endif
 +
 +/* possible flags for cipher_ctx->flags */
 +#define CIPHER_FLAG_HMAC          0x01
@@ -1108,9 +985,7 @@
 +
 +#ifndef DEFAULT_CIPHER_FLAGS
 +#define DEFAULT_CIPHER_FLAGS CIPHER_FLAG_HMAC | CIPHER_FLAG_LE_PGNO
- #endif
--#ifdef SQLITE_NO_SYNC
--  "NO_SYNC",
++#endif
 +
 +
 +/* by default, sqlcipher will use a reduced number of iterations to generate
@@ -1118,9 +993,7 @@
 +   */
 +#ifndef FAST_PBKDF2_ITER
 +#define FAST_PBKDF2_ITER 2
- #endif
--#ifdef SQLITE_OMIT_ALTERTABLE
--  "OMIT_ALTERTABLE",
++#endif
 +
 +/* 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
@@ -1129,30 +1002,22 @@
 +   will likely allow this to be defined at runtime via pragma */ 
 +#ifndef HMAC_SALT_MASK
 +#define HMAC_SALT_MASK 0x3a
- #endif
--#ifdef SQLITE_OMIT_ANALYZE
--  "OMIT_ANALYZE",
++#endif
 +
 +#ifndef CIPHER_MAX_IV_SZ
 +#define CIPHER_MAX_IV_SZ 16
- #endif
--#ifdef SQLITE_OMIT_ATTACH
--  "OMIT_ATTACH",
++#endif
 +
 +#ifndef CIPHER_MAX_KEY_SZ
 +#define CIPHER_MAX_KEY_SZ 64
- #endif
--#ifdef SQLITE_OMIT_AUTHORIZATION
--  "OMIT_AUTHORIZATION",
++#endif
 +
 +
 +#ifdef CODEC_DEBUG
 +#define CODEC_TRACE(X)  {printf X;fflush(stdout);}
 +#else
 +#define CODEC_TRACE(X)
- #endif
--#ifdef SQLITE_OMIT_AUTOINCREMENT
--  "OMIT_AUTOINCREMENT",
++#endif
 +
 +#ifdef CODEC_DEBUG_PAGEDATA
 +#define CODEC_HEXDUMP(DESC,BUFFER,LEN)  \
@@ -1168,9 +1033,7 @@
 +  }
 +#else
 +#define CODEC_HEXDUMP(DESC,BUFFER,LEN)
- #endif
--#ifdef SQLITE_OMIT_AUTOINIT
--  "OMIT_AUTOINIT",
++#endif
 +
 +/* extensions defined in pager.c */ 
 +SQLITE_PRIVATE void sqlite3pager_get_codec(Pager *pPager, void **ctx);
@@ -1195,13 +1058,20 @@
 +         (c>='a' && c<='f') ? (c)-'a'+10 : 0;
 +}
 +
-+static void cipher_hex2bin(const char *hex, int sz, unsigned char *out){
++static void cipher_hex2bin(const unsigned char *hex, int sz, unsigned char *out){
 +  int i;
 +  for(i = 0; i < sz; i += 2){
 +    out[i/2] = (cipher_hex2int(hex[i])<<4) | cipher_hex2int(hex[i+1]);
 +  }
 +}
 +
++static void cipher_bin2hex(const unsigned char* in, int sz, char *out) {
++    int i;
++    for(i=0; i < sz; i++) {
++      sqlite3_snprintf(3, out + (i*2), "%02x ", in[i]);
++    } 
++}
++
 +/* extensions defined in crypto_impl.c */
 +typedef struct codec_ctx codec_ctx;
 +
@@ -1220,12 +1090,15 @@
 +void sqlcipher_codec_ctx_set_error(codec_ctx *, int);
 +
 +int sqlcipher_codec_ctx_set_pass(codec_ctx *, const void *, int, int);
-+void sqlcipher_codec_get_pass(codec_ctx *, void **zKey, int *nKey);
++void sqlcipher_codec_get_keyspec(codec_ctx *, void **zKey, int *nKey);
 +
 +int sqlcipher_codec_ctx_set_pagesize(codec_ctx *, int);
 +int sqlcipher_codec_ctx_get_pagesize(codec_ctx *);
 +int sqlcipher_codec_ctx_get_reservesize(codec_ctx *);
 +
++void sqlcipher_set_default_kdf_iter(int iter);
++int sqlcipher_get_default_kdf_iter();
++
 +int sqlcipher_codec_ctx_set_kdf_iter(codec_ctx *, int, int);
 +int sqlcipher_codec_ctx_get_kdf_iter(codec_ctx *ctx, int);
 +
@@ -1255,214 +1128,14 @@
 +int sqlcipher_codec_ctx_get_flag(codec_ctx *ctx, unsigned int flag, int for_ctx);
 +
 +const char* sqlcipher_codec_get_cipher_provider(codec_ctx *ctx);
- #endif
--#ifdef SQLITE_OMIT_AUTOMATIC_INDEX
--  "OMIT_AUTOMATIC_INDEX",
- #endif
--#ifdef SQLITE_OMIT_AUTORESET
--  "OMIT_AUTORESET",
--#endif
--#ifdef SQLITE_OMIT_AUTOVACUUM
--  "OMIT_AUTOVACUUM",
--#endif
--#ifdef SQLITE_OMIT_BETWEEN_OPTIMIZATION
--  "OMIT_BETWEEN_OPTIMIZATION",
--#endif
--#ifdef SQLITE_OMIT_BLOB_LITERAL
--  "OMIT_BLOB_LITERAL",
--#endif
--#ifdef SQLITE_OMIT_BTREECOUNT
--  "OMIT_BTREECOUNT",
--#endif
--#ifdef SQLITE_OMIT_BUILTIN_TEST
--  "OMIT_BUILTIN_TEST",
--#endif
--#ifdef SQLITE_OMIT_CAST
--  "OMIT_CAST",
--#endif
--#ifdef SQLITE_OMIT_CHECK
--  "OMIT_CHECK",
--#endif
--#ifdef SQLITE_OMIT_COMPLETE
--  "OMIT_COMPLETE",
--#endif
--#ifdef SQLITE_OMIT_COMPOUND_SELECT
--  "OMIT_COMPOUND_SELECT",
--#endif
--#ifdef SQLITE_OMIT_DATETIME_FUNCS
--  "OMIT_DATETIME_FUNCS",
--#endif
--#ifdef SQLITE_OMIT_DECLTYPE
--  "OMIT_DECLTYPE",
--#endif
--#ifdef SQLITE_OMIT_DEPRECATED
--  "OMIT_DEPRECATED",
--#endif
--#ifdef SQLITE_OMIT_DISKIO
--  "OMIT_DISKIO",
--#endif
--#ifdef SQLITE_OMIT_EXPLAIN
--  "OMIT_EXPLAIN",
--#endif
--#ifdef SQLITE_OMIT_FLAG_PRAGMAS
--  "OMIT_FLAG_PRAGMAS",
--#endif
--#ifdef SQLITE_OMIT_FLOATING_POINT
--  "OMIT_FLOATING_POINT",
--#endif
--#ifdef SQLITE_OMIT_FOREIGN_KEY
--  "OMIT_FOREIGN_KEY",
--#endif
--#ifdef SQLITE_OMIT_GET_TABLE
--  "OMIT_GET_TABLE",
--#endif
--#ifdef SQLITE_OMIT_INCRBLOB
--  "OMIT_INCRBLOB",
--#endif
--#ifdef SQLITE_OMIT_INTEGRITY_CHECK
--  "OMIT_INTEGRITY_CHECK",
--#endif
--#ifdef SQLITE_OMIT_LIKE_OPTIMIZATION
--  "OMIT_LIKE_OPTIMIZATION",
--#endif
--#ifdef SQLITE_OMIT_LOAD_EXTENSION
--  "OMIT_LOAD_EXTENSION",
--#endif
--#ifdef SQLITE_OMIT_LOCALTIME
--  "OMIT_LOCALTIME",
--#endif
--#ifdef SQLITE_OMIT_LOOKASIDE
--  "OMIT_LOOKASIDE",
--#endif
--#ifdef SQLITE_OMIT_MEMORYDB
--  "OMIT_MEMORYDB",
--#endif
--#ifdef SQLITE_OMIT_OR_OPTIMIZATION
--  "OMIT_OR_OPTIMIZATION",
--#endif
--#ifdef SQLITE_OMIT_PAGER_PRAGMAS
--  "OMIT_PAGER_PRAGMAS",
--#endif
--#ifdef SQLITE_OMIT_PRAGMA
--  "OMIT_PRAGMA",
--#endif
--#ifdef SQLITE_OMIT_PROGRESS_CALLBACK
--  "OMIT_PROGRESS_CALLBACK",
--#endif
--#ifdef SQLITE_OMIT_QUICKBALANCE
--  "OMIT_QUICKBALANCE",
--#endif
--#ifdef SQLITE_OMIT_REINDEX
--  "OMIT_REINDEX",
--#endif
--#ifdef SQLITE_OMIT_SCHEMA_PRAGMAS
--  "OMIT_SCHEMA_PRAGMAS",
--#endif
--#ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
--  "OMIT_SCHEMA_VERSION_PRAGMAS",
--#endif
--#ifdef SQLITE_OMIT_SHARED_CACHE
--  "OMIT_SHARED_CACHE",
--#endif
--#ifdef SQLITE_OMIT_SUBQUERY
--  "OMIT_SUBQUERY",
--#endif
--#ifdef SQLITE_OMIT_TCL_VARIABLE
--  "OMIT_TCL_VARIABLE",
--#endif
--#ifdef SQLITE_OMIT_TEMPDB
--  "OMIT_TEMPDB",
--#endif
--#ifdef SQLITE_OMIT_TRACE
--  "OMIT_TRACE",
--#endif
--#ifdef SQLITE_OMIT_TRIGGER
--  "OMIT_TRIGGER",
--#endif
--#ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
--  "OMIT_TRUNCATE_OPTIMIZATION",
--#endif
--#ifdef SQLITE_OMIT_UTF16
--  "OMIT_UTF16",
--#endif
--#ifdef SQLITE_OMIT_VACUUM
--  "OMIT_VACUUM",
--#endif
--#ifdef SQLITE_OMIT_VIEW
--  "OMIT_VIEW",
--#endif
--#ifdef SQLITE_OMIT_VIRTUALTABLE
--  "OMIT_VIRTUALTABLE",
--#endif
--#ifdef SQLITE_OMIT_WAL
--  "OMIT_WAL",
--#endif
--#ifdef SQLITE_OMIT_WSD
--  "OMIT_WSD",
--#endif
--#ifdef SQLITE_OMIT_XFER_OPT
--  "OMIT_XFER_OPT",
--#endif
--#ifdef SQLITE_PERFORMANCE_TRACE
--  "PERFORMANCE_TRACE",
--#endif
--#ifdef SQLITE_PROXY_DEBUG
--  "PROXY_DEBUG",
--#endif
--#ifdef SQLITE_RTREE_INT_ONLY
--  "RTREE_INT_ONLY",
--#endif
--#ifdef SQLITE_SECURE_DELETE
--  "SECURE_DELETE",
--#endif
--#ifdef SQLITE_SMALL_STACK
--  "SMALL_STACK",
--#endif
--#ifdef SQLITE_SOUNDEX
--  "SOUNDEX",
--#endif
--#ifdef 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
--  "TEST",
--#endif
--#if defined(SQLITE_THREADSAFE)
--  "THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE),
--#endif
--#ifdef SQLITE_USE_ALLOCA
--  "USE_ALLOCA",
--#endif
--#ifdef SQLITE_ZERO_MALLOC
--  "ZERO_MALLOC"
--#endif
--};
++int sqlcipher_codec_ctx_migrate(codec_ctx *ctx);
++#endif
++#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 sqlite3_compileoption_used(const char *zOptName){
--  int i, n;
--  if( sqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7;
--  n = sqlite3Strlen30(zOptName);
++
 +/************** End of crypto.h **********************************************/
 +/************** Continuing where we left off in crypto.c *********************/
- 
--  /* 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
--     && sqlite3CtypeMap[(unsigned char)azCompileOpt[i][n]]==0
--    ){
--      return 1;
++
 +static const char* codec_get_cipher_version() {
 +  return CIPHER_VERSION;
 +}
@@ -1505,7 +1178,7 @@
 +  return SQLITE_ERROR;
 +} 
 +
-+int codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLeft, const char *zRight) {
++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;
 +  int rc;
@@ -1514,8 +1187,15 @@
 +    sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
 +  }
 +
-+  CODEC_TRACE(("codec_pragma: entered db=%p iDb=%d pParse=%p zLeft=%s zRight=%s ctx=%p\n", db, iDb, pParse, 
zLeft, zRight, ctx));
-+
++  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_migrate")==0 && !zRight ){
++    if(ctx){
++      char *migrate_status = sqlite3_mprintf("%d", sqlcipher_codec_ctx_migrate(ctx));
++      codec_vdbe_return_static_string(pParse, "cipher_migrate", migrate_status);
++      sqlite3_free(migrate_status);
++    }
++  } else
 +  if( sqlite3StrICmp(zLeft, "cipher_provider")==0 && !zRight ){
 +    if(ctx) { codec_vdbe_return_static_string(pParse, "cipher_provider",
 +                                              sqlcipher_codec_get_cipher_provider(ctx));
@@ -1537,6 +1217,15 @@
 +  if( sqlite3StrICmp(zLeft, "rekey_cipher")==0 && zRight ){
 +    if(ctx) sqlcipher_codec_ctx_set_cipher(ctx, zRight, 1); // change write cipher only 
 +  }else
++  if( sqlite3StrICmp(zLeft,"cipher_default_kdf_iter")==0 ){
++    if( zRight ) {
++      sqlcipher_set_default_kdf_iter(atoi(zRight)); // change default KDF iterations
++    } else {
++      char *kdf_iter = sqlite3_mprintf("%d", sqlcipher_get_default_kdf_iter());
++      codec_vdbe_return_static_string(pParse, "cipher_default_kdf_iter", kdf_iter);
++      sqlite3_free(kdf_iter);
++    }
++  }else
 +  if( sqlite3StrICmp(zLeft, "kdf_iter")==0 ){
 +    if(ctx) {
 +      if( zRight ) {
@@ -1631,7 +1320,7 @@
 +      if(zRight) {
 +        if (sqlite3StrNICmp(zRight ,"x'", 2) == 0 && sqlite3Strlen30(zRight) == 5) {
 +          unsigned char mask = 0;
-+          const char *hex = zRight+2;
++          const unsigned char *hex = (const unsigned char *)zRight+2;
 +          cipher_hex2bin(hex,2,&mask);
 +          sqlcipher_set_hmac_salt_mask(mask);
 +        }
@@ -1640,21 +1329,14 @@
 +          codec_vdbe_return_static_string(pParse, "cipher_hmac_salt_mask", hmac_salt_mask);
 +          sqlite3_free(hmac_salt_mask);
 +      }
-     }
++    }
 +  }else {
 +    return 0;
-   }
--  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 *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.
@@ -1704,11 +1386,9 @@
 +    default:
 +      return pData;
 +      break;
-   }
--  return 0;
- }
- 
--#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
++  }
++}
++
 +SQLITE_PRIVATE void sqlite3FreeCodecArg(void *pCodecArg) {
 +  codec_ctx *ctx = (codec_ctx *) pCodecArg;
 +  if(pCodecArg == NULL) return;
@@ -1761,16 +1441,41 @@
 +  /* do nothing, security enhancements are always active */
 +}
 +
++static int sqlcipher_find_db_index(sqlite3 *db, const char *zDb) {
++  int db_index;
++  if(zDb == NULL){
++    return 0;
++  }
++  for(db_index = 0; db_index < db->nDb; db_index++) {
++    struct Db *pDb = &db->aDb[db_index];
++    if(strcmp(pDb->zName, zDb) == 0) {
++      return db_index;
++    }
++  }
++  return 0;
++}
++
 +SQLITE_API int 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));
++  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) {
++  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) {
-+    return sqlite3CodecAttach(db, 0, pKey, nKey); // operate only on the main db 
++    int db_index = sqlcipher_find_db_index(db, zDb);
++    return sqlite3CodecAttach(db, db_index, pKey, nKey); 
 +  }
 +  return SQLITE_ERROR;
 +}
 +
-+/* sqlite3_rekey 
++SQLITE_API int 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);
++}
++
++/* sqlite3_rekey_v2
 +** Given a database, this will reencrypt the database using a new key.
 +** There is only one possible modes of operation - to encrypt a database
 +** that is already encrpyted. If the database is not already encrypted
@@ -1780,11 +1485,12 @@
 +** 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(sqlite3 *db, const void *pKey, int nKey) {
-+  CODEC_TRACE(("sqlite3_rekey: entered db=%p pKey=%s, nKey=%d\n", db, (char *)pKey, nKey));
++SQLITE_API int 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) {
-+    struct Db *pDb = &db->aDb[0];
-+    CODEC_TRACE(("sqlite3_rekey: database pDb=%p\n", pDb));
++    int db_index = sqlcipher_find_db_index(db, zDb);
++    struct Db *pDb = &db->aDb[db_index];
++    CODEC_TRACE(("sqlite3_rekey_v2: database pDb=%p db_index:%d\n", pDb, db_index));
 +    if(pDb->pBt) {
 +      codec_ctx *ctx;
 +      int rc, page_count;
@@ -1796,13 +1502,13 @@
 +     
 +      if(ctx == NULL) { 
 +        /* there was no codec attached to this database, so this should do nothing! */ 
-+        CODEC_TRACE(("sqlite3_rekey: no codec attached to db, exiting\n"));
++        CODEC_TRACE(("sqlite3_rekey_v2: no codec attached to db, exiting\n"));
 +        return SQLITE_OK;
 +      }
 +
 +      sqlite3_mutex_enter(db->mutex);
 +
-+      codec_set_pass_key(db, 0, pKey, nKey, CIPHER_WRITE_CTX);
++      codec_set_pass_key(db, db_index, pKey, nKey, CIPHER_WRITE_CTX);
 +    
 +      /* do stuff here to rewrite the database 
 +      ** 1. Create a transaction on the database
@@ -1812,7 +1518,7 @@
 +      */
 +      rc = sqlite3BtreeBeginTrans(pDb->pBt, 1); /* begin write transaction */
 +      sqlite3PagerPagecount(pPager, &page_count);
-+      for(pgno = 1; rc == SQLITE_OK && pgno <= page_count; pgno++) { /* pgno's start at 1 see 
pager.c:pagerAcquire */
++      for(pgno = 1; rc == SQLITE_OK && pgno <= (unsigned int)page_count; pgno++) { /* pgno's start at 1 see 
pager.c:pagerAcquire */
 +        if(!sqlite3pager_is_mj_pgno(pPager, pgno)) { /* skip this page (see pager.c:pagerAcquire for 
reasoning) */
 +          rc = sqlite3PagerGet(pPager, pgno, &page);
 +          if(rc == SQLITE_OK) { /* write page see pager_incr_changecounter for example */
@@ -1820,21 +1526,21 @@
 +            if(rc == SQLITE_OK) {
 +              sqlite3PagerUnref(page);
 +            } else {
-+             CODEC_TRACE(("sqlite3_rekey: error %d occurred writing page %d\n", rc, pgno));  
++             CODEC_TRACE(("sqlite3_rekey_v2: error %d occurred writing page %d\n", rc, pgno));  
 +            }
 +          } else {
-+             CODEC_TRACE(("sqlite3_rekey: error %d occurred getting page %d\n", rc, pgno));  
++             CODEC_TRACE(("sqlite3_rekey_v2: error %d occurred getting page %d\n", rc, pgno));  
 +          }
 +        } 
 +      }
 +
 +      /* if commit was successful commit and copy the rekey data to current key, else rollback to release 
locks */
 +      if(rc == SQLITE_OK) { 
-+        CODEC_TRACE(("sqlite3_rekey: committing\n"));
++        CODEC_TRACE(("sqlite3_rekey_v2: committing\n"));
 +        rc = sqlite3BtreeCommit(pDb->pBt); 
 +        sqlcipher_codec_key_copy(ctx, CIPHER_WRITE_CTX);
 +      } else {
-+        CODEC_TRACE(("sqlite3_rekey: rollback\n"));
++        CODEC_TRACE(("sqlite3_rekey_v2: rollback\n"));
 +        sqlite3BtreeRollback(pDb->pBt, SQLITE_ABORT_ROLLBACK);
 +      }
 +
@@ -1848,13 +1554,11 @@
 +SQLITE_PRIVATE void sqlite3CodecGetKey(sqlite3* db, int nDb, void **zKey, int *nKey) {
 +  struct Db *pDb = &db->aDb[nDb];
 +  CODEC_TRACE(("sqlite3CodecGetKey: entered db=%p, nDb=%d\n", db, nDb));
-+  
 +  if( pDb->pBt ) {
 +    codec_ctx *ctx;
 +    sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
-+
 +    if(ctx) { /* if the codec has an attached codec_context user the raw key data */
-+      sqlcipher_codec_get_pass(ctx, zKey, nKey);
++      sqlcipher_codec_get_keyspec(ctx, zKey, nKey);
 +    } else {
 +      *zKey = NULL;
 +      *nKey = 0;
@@ -1863,26 +1567,8 @@
 +}
 +
 +#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 *****************************************/
++
++/*
 + * 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:
@@ -1896,29 +1582,12 @@
 + * named attached database.
 + */
 +
- /*
--** 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.
++/*
 +** 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 _VDBEINT_H_
--#define _VDBEINT_H_
++*/
 +static int sqlcipher_finalize(sqlite3 *db, sqlite3_stmt *pStmt, char **pzErrMsg){
 +  int rc;
 +  rc = sqlite3VdbeFinalize((Vdbe*)pStmt);
@@ -1927,17 +1596,12 @@
 +  }
 +  return rc;
 +}
- 
- /*
--** The maximum number of times that a statement will try to reparse
--** itself before giving up and returning SQLITE_SCHEMA.
++
++/*
 +** Execute zSql on database db. Return an error code.
 +** 
 +** Based on execSql from vacuum.c
- */
--#ifndef SQLITE_MAX_SCHEMA_RETRY
--# define SQLITE_MAX_SCHEMA_RETRY 50
--#endif
++*/
 +static int sqlcipher_execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
 +  sqlite3_stmt *pStmt;
 +  VVA_ONLY( int rc; )
@@ -1952,17 +1616,13 @@
 +  assert( rc!=SQLITE_ROW );
 +  return sqlcipher_finalize(db, pStmt, pzErrMsg);
 +}
- 
- /*
--** 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. The statement returns exactly
 +** one column. Execute this as SQL on the same database.
 +** 
 +** Based on execExecSql from vacuum.c
- */
--typedef struct VdbeOp Op;
++*/
 +static int sqlcipher_execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
 +  sqlite3_stmt *pStmt;
 +  int rc;
@@ -1980,14 +1640,12 @@
 +
 +  return sqlcipher_finalize(db, pStmt, pzErrMsg);
 +}
- 
- /*
--** Boolean values
++
++/*
 + * copy database and schema from the main database to an attached database
 + * 
 + * Based on sqlite3RunVacuum from vacuum.c
- */
--typedef unsigned char Bool;
++*/
 +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]);
@@ -2103,30 +1761,18 @@
 +    }
 +  }
 +}
- 
--/* Opaque type used by code in vdbesort.c */
--typedef struct VdbeSorter VdbeSorter;
++
 +#endif
- 
--/* Opaque type used by the explainer */
--typedef struct Explain Explain;
++
 +/* END SQLCIPHER */
 +#endif
- 
--/*
--** 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.
++
 +/************** End of crypto.c **********************************************/
 +/************** Begin file crypto_impl.c *************************************/
 +/* 
 +** SQLCipher
 +** http://sqlcipher.net
- ** 
--** Every cursor that the virtual machine has open is represented by an
--** instance of the following structure.
++** 
 +** Copyright (c) 2008 - 2013, ZETETIC LLC
 +** All rights reserved.
 +** 
@@ -2152,37 +1798,10 @@
 +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 +**  
- */
--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 iDb;              /* Index of cursor database in db->aDb[] (or -1) */
--  int pseudoTableReg;   /* Register holding pseudotable content. */
--  int nField;           /* Number of fields in the header */
--  Bool zeroed;          /* True if zeroed out and ready for reuse */
--  Bool rowidIsValid;    /* True if lastRowid is valid */
--  Bool atFirst;         /* True if pointing to first entry */
--  Bool useRandomRowid;  /* Generate new record numbers semi-randomly */
--  Bool nullRow;         /* True if pointing to a row with no data */
--  Bool deferredMoveto;  /* A call to sqlite3BtreeMoveto() is needed */
--  Bool isTable;         /* True if a table requiring integer keys */
--  Bool isIndex;         /* True if an index containing keys only - no data */
--  Bool isOrdered;       /* True if the underlying table is BTREE_UNORDERED */
--  Bool isSorter;        /* True if a new-style sorter */
--  Bool multiPseudo;     /* Multi-register pseudo-cursor */
--  sqlite3_vtab_cursor *pVtabCursor;  /* The cursor for a virtual table */
--  const sqlite3_module *pModule;     /* Module for cursor pVtabCursor */
--  i64 seqCount;         /* Sequence counter */
--  i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
--  i64 lastRowid;        /* Last rowid from a Next or NextIdx operation */
--  VdbeSorter *pSorter;  /* Sorter object for OP_SorterOpen cursors */
++*/
 +/* BEGIN SQLCIPHER */
 +#ifdef SQLITE_HAS_CODEC
- 
--  /* Result of last sqlite3BtreeMoveto() done by an OP_NotExists or 
--  ** OP_IsUnique opcode on this cursor. */
--  int seekResult;
++
 +/************** Include sqlcipher.h in the middle of crypto_impl.c ***********/
 +/************** Begin file sqlcipher.h ***************************************/
 +/* 
@@ -2221,21 +1840,7 @@
 +#ifdef SQLITE_HAS_CODEC
 +#ifndef SQLCIPHER_H
 +#define SQLCIPHER_H
- 
--  /* 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 */
--  int payloadSize;      /* Total number of bytes in the record */
--  u32 *aType;           /* Type values for all entries in the record */
--  u32 *aOffset;         /* Cached offsets to the start of each columns data */
--  u8 *aRow;             /* Data for the current row, if all on one page */
++
 +
 +typedef struct {
 +  int (*activate)(void *ctx);
@@ -2244,7 +1849,7 @@
 +  int (*add_random)(void *ctx, void *buffer, int length);
 +  int (*random)(void *ctx, void *buffer, int length);
 +  int (*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);
-+  int (*kdf)(void *ctx, const char *pass, int pass_sz, unsigned char* salt, int salt_sz, int workfactor, 
int key_sz, unsigned char *key);
++  int (*kdf)(void *ctx, const unsigned char *pass, int pass_sz, unsigned char* salt, int salt_sz, int 
workfactor, int key_sz, unsigned char *key);
 +  int (*cipher)(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, unsigned char *in, 
int in_sz, unsigned char *out);
 +  int (*set_cipher)(void *ctx, const char *cipher_name);
 +  const char* (*get_cipher)(void *ctx);
@@ -2298,16 +1903,19 @@
 +  int pass_sz;
 +  int reserve_sz;
 +  int hmac_sz;
++  int keyspec_sz;
 +  unsigned int flags;
 +  unsigned char *key;
 +  unsigned char *hmac_key;
-+  char *pass;
++  unsigned char *pass;
++  char *keyspec;
 +  sqlcipher_provider *provider;
 +  void *provider_ctx;
 +} cipher_ctx;
 +
 +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 unsigned int sqlcipher_activate_count = 0;
 +static sqlite3_mutex* sqlcipher_provider_mutex = NULL;
 +static sqlcipher_provider *default_provider = NULL;
@@ -2321,49 +1929,9 @@
 +  Btree *pBt;
 +  cipher_ctx *read_ctx;
 +  cipher_ctx *write_ctx;
- };
--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 */
--  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.nChanges)     */
--};
++  unsigned int skip_read_hmac;
++};
++
 +int sqlcipher_register_provider(sqlcipher_provider *p) {
 +  sqlite3_mutex_enter(sqlcipher_provider_mutex);
 +  if(default_provider != NULL && default_provider != p) {
@@ -2376,45 +1944,17 @@
 +  sqlite3_mutex_leave(sqlcipher_provider_mutex);
 +  return SQLITE_OK;
 +}
- 
--#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
++
 +/* 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;
 +}
- 
--/*
--** A value for VdbeCursor.cacheValid that means the cache is always invalid.
--*/
--#define CACHE_STALE 0
++
 +void sqlcipher_activate() {
 +  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
- 
--/*
--** 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 {
--  sqlite3 *db;        /* The associated database connection */
--  char *z;            /* String or BLOB value */
--  double r;           /* Real value */
--  union {
--    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  type;           /* One of SQLITE_NULL, SQLITE_TEXT, SQLITE_INTEGER, etc */
--  u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
--#ifdef SQLITE_DEBUG
--  Mem *pScopyFrom;    /* This Mem is a shallow copy of pScopyFrom */
--  void *pFiller;      /* So that sizeof(Mem) is a multiple of 8 */
++
 +  if(sqlcipher_provider_mutex == NULL) {
 +    /* allocate a new mutex to guard access to the provider */
 +    sqlcipher_provider_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
@@ -2436,55 +1976,15 @@
 +    sqlcipher_openssl_setup(p);
 +#else
 +#error "NO DEFAULT SQLCIPHER CRYPTO PROVIDER DEFINED"
- #endif
--  void (*xDel)(void *);  /* If not null, call this function to delete Mem.z */
--  char *zMalloc;      /* Dynamic buffer allocated by sqlite3_malloc() */
--};
++#endif
 +    sqlcipher_register_provider(p);
 +  }
- 
--/* 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_RowSet    0x0020   /* Value is a RowSet object */
--#define MEM_Frame     0x0040   /* Value is a VdbeFrame object */
--#define MEM_Invalid   0x0080   /* Value is undefined */
--#define MEM_Cleared   0x0100   /* NULL set by OP_Null, not from data */
--#define MEM_TypeMask  0x01ff   /* Mask of type bits */
++
 +  sqlcipher_activate_count++; /* increment activation count */
- 
++
 +  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
 +}
- 
--/* 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 sqliteFree() 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_deactivate() {
 +  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
 +  sqlcipher_activate_count--;
@@ -2500,163 +2000,40 @@
 +    /* last connection closed, free provider mutex*/
 +    sqlite3_mutex_free(sqlcipher_provider_mutex); 
 +    sqlcipher_provider_mutex = NULL;
- 
--/*
--** 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)
++
 +    sqlcipher_activate_count = 0; /* reset activation count */
 +  }
 +  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
 +}
- 
--/*
--** Return true if a memory cell is not marked as invalid.  This macro
--** is for use inside assert() statements only.
++
 +/* 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)
- */
--#ifdef SQLITE_DEBUG
--#define memIsValid(M)  ((M)->flags & MEM_Invalid)==0
--#endif
++*/
 +void* sqlcipher_memset(void *v, unsigned char value, int len) {
 +  int i = 0;
 +  volatile unsigned char *a = v;
- 
++
 +  if (v == NULL) return v;
- 
--/* A VdbeFunc is just a FuncDef (defined in sqliteInt.h) that contains
--** additional information about auxiliary information bound to arguments
--** of the function.  This is used to implement the sqlite3_get_auxdata()
--** and sqlite3_set_auxdata() APIs.  The "auxdata" is some auxiliary data
--** that can be associated with a constant argument to a function.  This
--** allows functions such as "regexp" to compile their constant regular
--** expression argument once and reused the compiled code for multiple
--** invocations.
--*/
--struct VdbeFunc {
--  FuncDef *pFunc;               /* The definition of the function */
--  int nAux;                     /* Number of entries allocated for apAux[] */
--  struct AuxData {
--    void *pAux;                   /* Aux data for the i-th argument */
--    void (*xDelete)(void *);      /* Destructor for the aux data */
--  } apAux[1];                   /* One slot for each function argument */
--};
++
 +  for(i = 0; i < len; i++) {
 +    a[i] = value;
 +  }
- 
--/*
--** The "context" argument for a 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 {
--  FuncDef *pFunc;       /* Pointer to function information.  MUST BE FIRST */
--  VdbeFunc *pVdbeFunc;  /* Auxilary data, if created. */
--  Mem s;                /* The return value is stored here */
--  Mem *pMem;            /* Memory cell used to store aggregate context */
--  CollSeq *pColl;       /* Collating sequence */
--  int isError;          /* Error code returned by the function. */
--  int skipFlag;         /* Skip skip accumulator loading if true */
--};
++
 +  return v;
 +}
- 
--/*
--** 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 */
--};
++
 +/* 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;
- 
--/* 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 */
++
 +  for(i = 0; i < len; i++) {
 +    result |= a[i] ^ value;
 +  }
- 
--/*
--** 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 */
--  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 */
--  int nMem;               /* Number of memory locations currently allocated */
--  int nOp;                /* Number of instructions in the program */
--  int nOpAlloc;           /* Number of slots allocated for aOp[] */
--  int nLabel;             /* Number of labels used */
--  int *aLabel;            /* Space to hold the labels */
--  u16 nResColumn;         /* Number of columns in one row of the result set */
--  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 */
--  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 */
--  bft usesStmtJournal:1;  /* True if uses a statement journal */
--  bft readOnly:1;         /* True for read-only statements */
--  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) */
--  int aCounter[3];        /* Counters used by sqlite3_stmt_status() */
--#ifndef SQLITE_OMIT_TRACE
--  i64 startTime;          /* Time when query started - used for profiling */
++
 +  return (result != 0);
 +}
 +
@@ -2689,18 +2066,11 @@
 +#if defined(__unix__) || defined(__APPLE__) 
 +      munlock(ptr, sz);
 +#elif defined(_WIN32)
-+      VirtualUnlock(ptr, sz);
- #endif
--  i64 nFkConstraint;      /* Number of imm. FK constraints this VM */
--  i64 nStmtDefCons;       /* Number of def. constraints when stmt started */
--  char *zSql;             /* Text of the SQL statement that generated this */
--  void *pFree;            /* Free this when deleting the vdbe */
--#ifdef SQLITE_DEBUG
--  FILE *trace;            /* Write an execution trace here, if not NULL */
- #endif
--#ifdef SQLITE_ENABLE_TREE_EXPLAIN
--  Explain *pExplain;      /* The explainer */
--  char *zExplain;         /* Explanation of data structures */
++#if !(defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP || WINAPI_FAMILY == 
WINAPI_FAMILY_APP))
++VirtualUnlock(ptr, sz);
++#endif
++#endif
++#endif
 +    }
 +    sqlite3_free(ptr);
 +  }
@@ -2719,43 +2089,16 @@
 +#if defined(__unix__) || defined(__APPLE__) 
 +    mlock(ptr, sz);
 +#elif defined(_WIN32)
++#if !(defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP || WINAPI_FAMILY == 
WINAPI_FAMILY_APP))
 +    VirtualLock(ptr, sz);
- #endif
--  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 */
--};
++#endif
++#endif
 +  }
 +#endif
 +  return ptr;
 +}
- 
--/*
--** 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*);
--#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*, int, Mem*, int);
--SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
--SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);
++
++
 +/**
 +  * Initialize new cipher_ctx struct. This function will allocate memory
 +  * for the cipher context and for the key
@@ -2783,72 +2126,13 @@
 +  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;
- 
--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 sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
--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 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 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 int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
--SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
--SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p);
--#define VdbeMemRelease(X)  \
--  if((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame)) \
--    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 sqlite3VdbeCloseStatement(Vdbe *, int);
--SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*);
--SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *);
--SQLITE_PRIVATE void sqlite3VdbeMemStoreType(Mem *pMem);
--SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p);
++
 +  /* setup default flags */
 +  ctx->flags = default_flags;
- 
--SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *);
--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 sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int *);
++
 +  return SQLITE_OK;
 +}
- 
--#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
++
 +/**
 +  * Free and wipe memory associated with a cipher_ctx
 +  */
@@ -2860,6 +2144,7 @@
 +  sqlcipher_free(ctx->key, ctx->key_sz);
 +  sqlcipher_free(ctx->hmac_key, ctx->key_sz);
 +  sqlcipher_free(ctx->pass, ctx->pass_sz);
++  sqlcipher_free(ctx->keyspec, ctx->keyspec_sz);
 +  sqlcipher_free(ctx, sizeof(cipher_ctx)); 
 +}
 +
@@ -2890,10 +2175,7 @@
 +  ) return 0;
 +  return 1;
 +}
- 
--#ifdef SQLITE_DEBUG
--SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe*,Mem*);
--#endif
++
 +/**
 +  * Copy one cipher_ctx to another. For instance, assuming that read_ctx is a 
 +  * fully initialized context, you could copy it to write_ctx and all yet data
@@ -2910,103 +2192,90 @@
 +
 +  CODEC_TRACE(("sqlcipher_cipher_ctx_copy: entered target=%p, source=%p\n", target, source));
 +  sqlcipher_free(target->pass, target->pass_sz); 
++  sqlcipher_free(target->keyspec, target->keyspec_sz); 
 +  memcpy(target, source, sizeof(cipher_ctx));
-+  
++
 +  target->key = key; //restore pointer to previously allocated key data
 +  memcpy(target->key, source->key, CIPHER_MAX_KEY_SZ);
- 
--#ifndef SQLITE_OMIT_FOREIGN_KEY
--SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *, int);
--#else
--# define sqlite3VdbeCheckFk(p,i) 0
--#endif
++
 +  target->hmac_key = hmac_key; //restore pointer to previously allocated hmac key data
 +  memcpy(target->hmac_key, source->hmac_key, CIPHER_MAX_KEY_SZ);
- 
--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);
++
 +  target->provider = provider; // restore pointer to previouly allocated provider;
 +  memcpy(target->provider, source->provider, sizeof(sqlcipher_provider));
- 
--#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
++
 +  target->provider_ctx = provider_ctx; // restore pointer to previouly allocated provider context;
 +  target->provider->ctx_copy(target->provider_ctx, source->provider_ctx);
- 
--#endif /* !defined(_VDBEINT_H_) */
-+  target->pass = sqlcipher_malloc(source->pass_sz);
-+  if(target->pass == NULL) return SQLITE_NOMEM;
-+  memcpy(target->pass, source->pass, source->pass_sz);
- 
--/************** End of vdbeInt.h *********************************************/
--/************** Continuing where we left off in status.c *********************/
++
++  if(source->pass && source->pass_sz) {
++    target->pass = sqlcipher_malloc(source->pass_sz);
++    if(target->pass == NULL) return SQLITE_NOMEM;
++    memcpy(target->pass, source->pass, source->pass_sz);
++  }
++  if(source->keyspec && source->keyspec_sz) {
++    target->keyspec = sqlcipher_malloc(source->keyspec_sz);
++    if(target->keyspec == NULL) return SQLITE_NOMEM;
++    memcpy(target->keyspec, source->keyspec, source->keyspec_sz);
++  }
 +  return SQLITE_OK;
 +}
- 
--/*
--** Variables in which to record status information.
--*/
--typedef struct sqlite3StatType sqlite3StatType;
--static SQLITE_WSD struct sqlite3StatType {
--  int nowValue[10];         /* Current value */
--  int mxValue[10];          /* Maximum value */
--} sqlite3Stat = { {0,}, {0,} };
- 
++
++/**
++  * Set the keyspec for the cipher_ctx
++  * 
++  * returns SQLITE_OK if assignment was successfull
++  * returns SQLITE_NOMEM if an error occured allocating memory
++  */
++static int sqlcipher_cipher_ctx_set_keyspec(cipher_ctx *ctx, const unsigned char *key, int key_sz, const 
unsigned char *salt, int salt_sz) {
++
++    /* free, zero existing pointers and size */
++  sqlcipher_free(ctx->keyspec, ctx->keyspec_sz);
++  ctx->keyspec = NULL;
++  ctx->keyspec_sz = 0;
++
++  /* establic a hex-formated key specification, containing the raw encryption key and
++     the salt used to generate it */
++  ctx->keyspec_sz = ((key_sz + salt_sz) * 2) + 3;
++  ctx->keyspec = sqlcipher_malloc(ctx->keyspec_sz);
++  if(ctx->keyspec == NULL) return SQLITE_NOMEM;
++
++  ctx->keyspec[0] = 'x';
++  ctx->keyspec[1] = '\'';
++  cipher_bin2hex(key, key_sz, ctx->keyspec + 2);
++  cipher_bin2hex(salt, salt_sz, ctx->keyspec + (key_sz * 2) + 2);
++  ctx->keyspec[ctx->keyspec_sz - 1] = '\'';
++  return SQLITE_OK;
++}
++
 +/**
-+  * Set the raw password / key data for a cipher context
++  * Set the passphrase for the cipher_ctx
 +  * 
 +  * returns SQLITE_OK if assignment was successfull
 +  * returns SQLITE_NOMEM if an error occured allocating memory
-+  * returns SQLITE_ERROR if the key couldn't be set because the pass was null or size was zero
 +  */
 +static int sqlcipher_cipher_ctx_set_pass(cipher_ctx *ctx, const void *zKey, int nKey) {
++
++  /* free, zero existing pointers and size */
 +  sqlcipher_free(ctx->pass, ctx->pass_sz);
-+  ctx->pass_sz = nKey;
-+  if(zKey && nKey) {
++  ctx->pass = NULL;
++  ctx->pass_sz = 0;
++
++  if(zKey && nKey) { /* if new password is provided, copy it */
++    ctx->pass_sz = nKey;
 +    ctx->pass = sqlcipher_malloc(nKey);
 +    if(ctx->pass == NULL) return SQLITE_NOMEM;
 +    memcpy(ctx->pass, zKey, nKey);
-+    return SQLITE_OK;
-+  }
-+  return SQLITE_ERROR;
++  } 
++  return SQLITE_OK;
 +}
 +
 +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;
- 
--/* 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
++
 +  if((rc = sqlcipher_cipher_ctx_set_pass(c_ctx, zKey, nKey)) != SQLITE_OK) return rc; 
 +  c_ctx->derive_key = 1;
- 
--/*
--** Return the current value of a status parameter.
--*/
--SQLITE_PRIVATE int sqlite3StatusValue(int op){
--  wsdStatInit;
--  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
--  return wsdStat.nowValue[op];
++
 +  if(for_ctx == 2)
 +    if((rc = sqlcipher_cipher_ctx_copy( for_ctx ? ctx->read_ctx : ctx->write_ctx, c_ctx)) != SQLITE_OK) 
 +      return rc; 
@@ -3031,34 +2300,22 @@
 +      return rc; 
 +
 +  return SQLITE_OK;
- }
- 
--/*
--** Add N to the value of a status record.  It is assumed that the
--** caller holds appropriate locks.
--*/
--SQLITE_PRIVATE void sqlite3StatusAdd(int op, int N){
--  wsdStatInit;
--  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
--  wsdStat.nowValue[op] += N;
--  if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
--    wsdStat.mxValue[op] = wsdStat.nowValue[op];
--  }
++}
++
 +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;
 +  return c_ctx->provider->get_cipher(c_ctx->provider_ctx);
- }
- 
--/*
--** Set the value of a status to X.
--*/
--SQLITE_PRIVATE void sqlite3StatusSet(int op, int X){
--  wsdStatInit;
--  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
--  wsdStat.nowValue[op] = X;
--  if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
--    wsdStat.mxValue[op] = wsdStat.nowValue[op];
--  }
++}
++
++/* set the global default KDF iteration */
++void sqlcipher_set_default_kdf_iter(int iter) {
++  default_kdf_iter = iter; 
++}
++
++int sqlcipher_get_default_kdf_iter() {
++  return default_kdf_iter;
++}
++
 +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;
@@ -3071,25 +2328,8 @@
 +      return rc; 
 +
 +  return SQLITE_OK;
- }
- 
--/*
--** 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){
--  wsdStatInit;
--  if( op<0 || op>=ArraySize(wsdStat.nowValue) ){
--    return SQLITE_MISUSE_BKPT;
--  }
--  *pCurrent = wsdStat.nowValue[op];
--  *pHighwater = wsdStat.mxValue[op];
--  if( resetFlag ){
--    wsdStat.mxValue[op] = wsdStat.nowValue[op];
--  }
++}
++
 +int sqlcipher_codec_ctx_get_kdf_iter(codec_ctx *ctx, int for_ctx) {
 +  cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
 +  return c_ctx->kdf_iter;
@@ -3106,157 +2346,46 @@
 +    if((rc = sqlcipher_cipher_ctx_copy( for_ctx ? ctx->read_ctx : ctx->write_ctx, c_ctx)) != SQLITE_OK)
 +      return rc; 
 +
-   return SQLITE_OK;
- }
- 
--/*
--** Query status information for a single database connection
--*/
--SQLITE_API int 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 */
--  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;
--    }
++  return SQLITE_OK;
++}
++
 +int sqlcipher_codec_ctx_get_fast_kdf_iter(codec_ctx *ctx, int for_ctx) {
 +  cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
 +  return c_ctx->fast_kdf_iter;
 +}
- 
--    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;
--    }
++
 +/* set the global default flag for HMAC */
 +void sqlcipher_set_default_use_hmac(int use) {
 +  if(use) default_flags |= CIPHER_FLAG_HMAC; 
 +  else default_flags &= ~CIPHER_FLAG_HMAC; 
 +}
- 
--    /* 
--    ** 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;
--    }
++
 +int sqlcipher_get_default_use_hmac() {
 +  return (default_flags & CIPHER_FLAG_HMAC) != 0;
 +}
- 
--    /*
--    ** *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 */
++
 +void sqlcipher_set_hmac_salt_mask(unsigned char mask) {
 +  hmac_salt_mask = 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;
++
 +unsigned char sqlcipher_get_hmac_salt_mask() {
 +  return hmac_salt_mask;
 +}
- 
--          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);
++
 +/* set the codec flag for whether this individual database should be using hmac */
 +int sqlcipher_codec_ctx_set_use_hmac(codec_ctx *ctx, int use) {
 +  int reserve = CIPHER_MAX_IV_SZ; /* base reserve size will be IV only */ 
- 
--          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);
++
 +  if(use) reserve += ctx->read_ctx->hmac_sz; /* if reserve will include hmac, update that size */
- 
--      *pHighwater = 0;
--      *pCurrent = nByte;
--      break;
--    }
++
 +  /* calculate the amount of reserve needed in even increments of the cipher block size */
- 
--    /*
--    ** *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 */
++
 +  reserve = ((reserve % ctx->read_ctx->block_sz) == 0) ? reserve :
 +               ((reserve / ctx->read_ctx->block_sz) + 1) * ctx->read_ctx->block_sz;  
- 
--      db->pnBytesFreed = &nByte;
--      for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){
--        sqlite3VdbeClearObject(db, pVdbe);
--        sqlite3DbFree(db, pVdbe);
--      }
--      db->pnBytesFreed = 0;
++
 +  CODEC_TRACE(("sqlcipher_codec_ctx_set_use_hmac: use=%d block_sz=%d md_size=%d reserve=%d\n", 
 +                use, ctx->read_ctx->block_sz, ctx->read_ctx->hmac_sz, reserve)); 
- 
--      *pHighwater = 0;
--      *pCurrent = nByte;
++
 +  
 +  if(use) {
 +    sqlcipher_codec_ctx_set_flag(ctx, CIPHER_FLAG_HMAC);
@@ -3265,234 +2394,55 @@
 +  } 
 +  
 +  ctx->write_ctx->reserve_sz = ctx->read_ctx->reserve_sz = reserve;
- 
--      break;
--    }
++
 +  return SQLITE_OK;
 +}
- 
--    /*
--    ** 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 );
++
 +int sqlcipher_codec_ctx_get_use_hmac(codec_ctx *ctx, int for_ctx) {
 +  cipher_ctx * c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
 +  return (c_ctx->flags & CIPHER_FLAG_HMAC) != 0;
 +}
- 
--      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;
--      *pCurrent = nRet;
--      break;
--    }
++
 +int sqlcipher_codec_ctx_set_flag(codec_ctx *ctx, unsigned int flag) {
 +  ctx->write_ctx->flags |= flag;
 +  ctx->read_ctx->flags |= flag;
 +  return SQLITE_OK;
 +}
- 
--    default: {
--      rc = SQLITE_ERROR;
--    }
--  }
--  sqlite3_mutex_leave(db->mutex);
--  return rc;
++
 +int sqlcipher_codec_ctx_unset_flag(codec_ctx *ctx, unsigned int flag) {
 +  ctx->write_ctx->flags &= ~flag;
 +  ctx->read_ctx->flags &= ~flag;
 +  return SQLITE_OK;
- }
- 
--/************** 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 implemention 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>
++}
++
 +int sqlcipher_codec_ctx_get_flag(codec_ctx *ctx, unsigned int flag, int for_ctx) {
 +  cipher_ctx * c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
 +  return (c_ctx->flags & flag) != 0;
 +}
- 
--#ifndef SQLITE_OMIT_DATETIME_FUNCS
++
 +void sqlcipher_codec_ctx_set_error(codec_ctx *ctx, int error) {
 +  CODEC_TRACE(("sqlcipher_codec_ctx_set_error: ctx=%p, error=%d\n", ctx, error));
 +  sqlite3pager_sqlite3PagerSetError(ctx->pBt->pBt->pPager, error);
 +  ctx->pBt->pBt->db->errCode = error;
 +}
- 
++
 +int sqlcipher_codec_ctx_get_reservesize(codec_ctx *ctx) {
 +  return ctx->read_ctx->reserve_sz;
 +}
- 
--/*
--** 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 */
--};
++
 +void* sqlcipher_codec_ctx_get_data(codec_ctx *ctx) {
 +  return ctx->buffer;
 +}
- 
++
 +void* sqlcipher_codec_ctx_get_kdf_salt(codec_ctx *ctx) {
 +  return ctx->kdf_salt;
 +}
- 
--/*
--** 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;
-+void sqlcipher_codec_get_pass(codec_ctx *ctx, void **zKey, int *nKey) {
-+  *zKey = ctx->read_ctx->pass;
-+  *nKey = ctx->read_ctx->pass_sz;
- }
- 
--/*
--** 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;
++
++void sqlcipher_codec_get_keyspec(codec_ctx *ctx, void **zKey, int *nKey) {
++  *zKey = ctx->read_ctx->keyspec;
++  *nKey = ctx->read_ctx->keyspec_sz;
++}
++
 +int sqlcipher_codec_ctx_set_pagesize(codec_ctx *ctx, int size) {
 +  /* attempt to free the existing page buffer */
 +  sqlcipher_free(ctx->buffer,ctx->page_sz);
@@ -3549,15 +2499,10 @@
 +  if(fd == NULL || sqlite3OsRead(fd, ctx->kdf_salt, FILE_HEADER_SZ, 0) != SQLITE_OK) {
 +    /* if unable to read the bytes, generate random salt */
 +    if(ctx->read_ctx->provider->random(ctx->read_ctx->provider_ctx, ctx->kdf_salt, FILE_HEADER_SZ) != 
SQLITE_OK) return SQLITE_ERROR;
-   }
--  zDate += 5;
--  p->tz = sgn*(nMn + nHr*60);
--zulu_time:
--  while( sqlite3Isspace(*zDate) ){ zDate++; }
--  return *zDate!=0;
++  }
 +
 +  if((rc = sqlcipher_codec_ctx_set_cipher(ctx, CIPHER, 0)) != SQLITE_OK) return rc;
-+  if((rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, PBKDF2_ITER, 0)) != SQLITE_OK) return rc;
++  if((rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, default_kdf_iter, 0)) != SQLITE_OK) return rc;
 +  if((rc = sqlcipher_codec_ctx_set_fast_kdf_iter(ctx, FAST_PBKDF2_ITER, 0)) != SQLITE_OK) return rc;
 +  if((rc = sqlcipher_codec_ctx_set_pass(ctx, zKey, nKey, 0)) != SQLITE_OK) return rc;
 +
@@ -3620,26 +2565,9 @@
 +    in_sz, (unsigned char*) &pgno_raw,
 +    sizeof(pgno), out);
 +  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;
--  }
--  zDate += 5;
--  if( *zDate==':' ){
--    zDate++;
--    if( getDigits(zDate, 2, 0, 59, 0, &s)!=1 ){
--      return 1;
++}
++
++/*
 + * ctx - codec context
 + * pgno - page number in database
 + * size - size in bytes of input and output buffers
@@ -3680,20 +2608,12 @@
 +    memcpy(iv_out, iv_in, c_ctx->iv_sz); /* copy the iv from the input to output buffer */
 +  } 
 +
-+  if((c_ctx->flags & CIPHER_FLAG_HMAC) && (mode == CIPHER_DECRYPT)) {
++  if((c_ctx->flags & CIPHER_FLAG_HMAC) && (mode == CIPHER_DECRYPT) && !ctx->skip_read_hmac) {
 +    if(sqlcipher_page_hmac(c_ctx, pgno, in, size + c_ctx->iv_sz, hmac_out) != SQLITE_OK) {
 +      sqlcipher_memset(out, 0, page_sz); 
 +      CODEC_TRACE(("codec_cipher: hmac operations failed for pgno=%d\n", pgno));
 +      return SQLITE_ERROR;
-     }
--    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++;
++    }
 +
 +    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 */ 
@@ -3712,45 +2632,30 @@
 +              CODEC_TRACE(("codec_cipher: hmac check failed for pgno=%d returning SQLITE_ERROR\n", pgno));
 +        sqlcipher_memset(out, 0, page_sz); 
 +              return SQLITE_ERROR;
-       }
--      ms /= rScale;
-     }
--  }else{
--    s = 0;
++      }
++    }
 +  } 
 +  
 +  c_ctx->provider->cipher(c_ctx->provider_ctx, mode, c_ctx->key, c_ctx->key_sz, iv_out, in, size, out);
 +
 +  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); 
-   }
--  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;
++  }
 +
 +  CODEC_HEXDUMP("codec_cipher: output page data", out_start, page_sz);
 +
 +  return SQLITE_OK;
- }
- 
--/*
--** 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;
++}
++
 +/**
 +  * Derive an encryption key for a cipher contex key based on the raw password.
 +  *
 +  * If the raw key data is formated as x'hex' and there are exactly enough hex chars to fill
-+  * the key space (i.e 64 hex chars for a 256 bit key) then the key data will be used directly. 
++  * the key (i.e 64 hex chars for a 256 bit key) then the key data will be used directly. 
++
++  * Else, if the raw key data is formated as x'hex' and there are exactly enough hex chars to fill
++  * the key and the salt (i.e 92 hex chars for a 256 bit key and 16 byte salt) then it will be unpacked
++  * as the key followed by the salt.
 +  * 
 +  * Otherwise, a key data will be derived using PBKDF2
 +  * 
@@ -3758,7 +2663,8 @@
 +  * returns SQLITE_ERROR if the key could't be derived (for instance if pass is NULL or pass_sz is 0)
 +  */
 +static int sqlcipher_cipher_ctx_key_derive(codec_ctx *ctx, cipher_ctx *c_ctx) {
-+  CODEC_TRACE(("codec_key_derive: entered c_ctx->pass=%s, c_ctx->pass_sz=%d \
++  int rc;
++  CODEC_TRACE(("cipher_ctx_key_derive: entered c_ctx->pass=%s, c_ctx->pass_sz=%d \
 +                ctx->kdf_salt=%p ctx->kdf_salt_sz=%d c_ctx->kdf_iter=%d \
 +                ctx->hmac_kdf_salt=%p, c_ctx->fast_kdf_iter=%d c_ctx->key_sz=%d\n", 
 +                c_ctx->pass, c_ctx->pass_sz, ctx->kdf_salt, ctx->kdf_salt_sz, c_ctx->kdf_iter, 
@@ -3766,38 +2672,32 @@
 +                
 +
 +  if(c_ctx->pass && c_ctx->pass_sz) { // if pass is not null
-+    if (c_ctx->pass_sz == ((c_ctx->key_sz*2)+3) && sqlite3StrNICmp(c_ctx->pass ,"x'", 2) == 0) { 
++    if (c_ctx->pass_sz == ((c_ctx->key_sz * 2) + 3) && sqlite3StrNICmp((const char *)c_ctx->pass ,"x'", 2) 
== 0) { 
 +      int n = c_ctx->pass_sz - 3; /* adjust for leading x' and tailing ' */
-+      const char *z = c_ctx->pass + 2; /* adjust lead offset of x' */
-+      CODEC_TRACE(("codec_key_derive: using raw key from hex\n")); 
++      const unsigned char *z = c_ctx->pass + 2; /* adjust lead offset of x' */
++      CODEC_TRACE(("cipher_ctx_key_derive: using raw key from hex\n")); 
 +      cipher_hex2bin(z, n, c_ctx->key);
++    } else if (c_ctx->pass_sz == (((c_ctx->key_sz + ctx->kdf_salt_sz) * 2) + 3) && sqlite3StrNICmp((const 
char *)c_ctx->pass ,"x'", 2) == 0) { 
++      const unsigned char *z = c_ctx->pass + 2; /* adjust lead offset of x' */
++      CODEC_TRACE(("cipher_ctx_key_derive: using raw key from hex\n")); 
++      cipher_hex2bin(z, (c_ctx->key_sz * 2), c_ctx->key);
++      cipher_hex2bin(z + (c_ctx->key_sz * 2), (ctx->kdf_salt_sz * 2), ctx->kdf_salt);
 +    } else { 
-+      CODEC_TRACE(("codec_key_derive: deriving key using full PBKDF2 with %d iterations\n", 
c_ctx->kdf_iter)); 
-+      c_ctx->provider->kdf(c_ctx->provider_ctx, (const char*) c_ctx->pass, c_ctx->pass_sz, 
++      CODEC_TRACE(("cipher_ctx_key_derive: deriving key using full PBKDF2 with %d iterations\n", 
c_ctx->kdf_iter)); 
++      c_ctx->provider->kdf(c_ctx->provider_ctx, c_ctx->pass, c_ctx->pass_sz, 
 +                    ctx->kdf_salt, ctx->kdf_salt_sz, c_ctx->kdf_iter,
 +                    c_ctx->key_sz, c_ctx->key);
-+                              
 +    }
 +
++    /* set the context "keyspec" containing the hex-formatted key and salt to be used when attaching 
databases */
++    if((rc = sqlcipher_cipher_ctx_set_keyspec(c_ctx, c_ctx->key, c_ctx->key_sz, ctx->kdf_salt, 
ctx->kdf_salt_sz)) != SQLITE_OK) return rc;
++
 +    /* if this context is setup to use hmac checks, generate a seperate and different 
 +       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;
- 
--  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;
++
 +      /* 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 
@@ -3808,11 +2708,11 @@
 +        ctx->hmac_kdf_salt[i] ^= hmac_salt_mask;
 +      } 
 +
-+      CODEC_TRACE(("codec_key_derive: deriving hmac key from encryption key using PBKDF2 with %d 
iterations\n", 
++      CODEC_TRACE(("cipher_ctx_key_derive: deriving hmac key from encryption key using PBKDF2 with %d 
iterations\n", 
 +        c_ctx->fast_kdf_iter)); 
 +
 +      
-+      c_ctx->provider->kdf(c_ctx->provider_ctx, (const char*)c_ctx->key, c_ctx->key_sz, 
++      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); 
 +    }
@@ -3827,29 +2727,21 @@
 +  /* derive key on first use if necessary */
 +  if(ctx->read_ctx->derive_key) {
 +    if(sqlcipher_cipher_ctx_key_derive(ctx, ctx->read_ctx) != SQLITE_OK) return SQLITE_ERROR;
-   }
--  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;
++  }
 +
 +  if(ctx->write_ctx->derive_key) {
 +    if(sqlcipher_cipher_ctx_cmp(ctx->write_ctx, ctx->read_ctx) == 0) {
-+      // the relevant parameters are the same, just copy read key
++      /* the relevant parameters are the same, just copy read key */
 +      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;
-     }
-   }
++    }
++  }
++
++  /* TODO: wipe and free passphrase after key derivation */
++  sqlcipher_cipher_ctx_set_pass(ctx->read_ctx, NULL, 0);
++  sqlcipher_cipher_ctx_set_pass(ctx->write_ctx, NULL, 0);
++
 +  return SQLITE_OK; 
 +}
 +
@@ -3863,22 +2755,227 @@
 +
 +const char* sqlcipher_codec_get_cipher_provider(codec_ctx *ctx) {
 +  return ctx->read_ctx->provider->get_provider_name(ctx->read_ctx);
- }
- 
++}
++
++
++static int sqlcipher_check_connection(const char *filename, char *key, int key_sz, char *sql, int 
*user_version) {
++  int rc;
++  sqlite3 *db = NULL;
++  sqlite3_stmt *statement = NULL;
++  char *query_user_version = "PRAGMA user_version;";
++  
++  rc = sqlite3_open(filename, &db);
++  if(rc != SQLITE_OK){
++    goto cleanup;
++  }
++  rc = sqlite3_key(db, key, key_sz);
++  if(rc != SQLITE_OK){
++    goto cleanup;
++  }
++  rc = sqlite3_exec(db, sql, NULL, NULL, NULL);
++  if(rc != SQLITE_OK){
++    goto cleanup;
++  }
++  rc = sqlite3_prepare(db, query_user_version, -1, &statement, NULL);
++  if(rc != SQLITE_OK){
++    goto cleanup;
++  }
++  rc = sqlite3_step(statement);
++  if(rc == SQLITE_ROW){
++    *user_version = sqlite3_column_int(statement, 0);
++    rc = SQLITE_OK;
++  }
++  
++cleanup:
++  if(statement){
++    sqlite3_finalize(statement);
++  }
++  if(db){
++    sqlite3_close(db);
++  }
++  return rc;
++}
++
++int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
++  u32 meta;
++  int rc = 0;
++  int command_idx = 0;
++  int password_sz;
++  int saved_flags;
++  int saved_nChange;
++  int saved_nTotalChange;
++  void (*saved_xTrace)(void*,const char*);
++  Db *pDb = 0;
++  sqlite3 *db = ctx->pBt->db;
++  const char *db_filename = sqlite3_db_filename(db, "main");
++  char *migrated_db_filename = sqlite3_mprintf("%s-migrated", db_filename);
++  char *pragma_hmac_off = "PRAGMA cipher_use_hmac = OFF;";
++  char *pragma_4k_kdf_iter = "PRAGMA kdf_iter = 4000;";
++  char *pragma_1x_and_4k;
++  char *set_user_version;
++  char *key;
++  int key_sz;
++  int user_version = 0;
++  int upgrade_1x_format = 0;
++  int upgrade_4k_format = 0;
++  static const unsigned char aCopy[] = {
++    BTREE_SCHEMA_VERSION,     1,  /* Add one to the old schema cookie */
++    BTREE_DEFAULT_CACHE_SIZE, 0,  /* Preserve the default page cache size */
++    BTREE_TEXT_ENCODING,      0,  /* Preserve the text encoding */
++    BTREE_USER_VERSION,       0,  /* Preserve the user version */
++    BTREE_APPLICATION_ID,     0,  /* Preserve the application id */
++  };
++
++
++  key_sz = ctx->read_ctx->pass_sz + 1;
++  key = sqlcipher_malloc(key_sz);
++  memset(key, 0, key_sz);
++  memcpy(key, ctx->read_ctx->pass, ctx->read_ctx->pass_sz);
++
++  if(db_filename){
++    const char* commands[5];
++    char *attach_command = sqlite3_mprintf("ATTACH DATABASE '%s-migrated' as migrate KEY '%q';",
++                                            db_filename, key);
++
++    int rc = sqlcipher_check_connection(db_filename, key, key_sz, "", &user_version);
++    if(rc == SQLITE_OK){
++      CODEC_TRACE(("No upgrade required - exiting\n"));
++      goto exit;
++    }
++    
++    // Version 2 - check for 4k with hmac format 
++    rc = sqlcipher_check_connection(db_filename, key, key_sz, pragma_4k_kdf_iter, &user_version);
++    if(rc == SQLITE_OK) {
++      CODEC_TRACE(("Version 2 format found\n"));
++      upgrade_4k_format = 1;
++    }
++
++    // Version 1 - check both no hmac and 4k together
++    pragma_1x_and_4k = sqlite3_mprintf("%s%s", pragma_hmac_off,
++                                             pragma_4k_kdf_iter);
++    rc = sqlcipher_check_connection(db_filename, key, key_sz, pragma_1x_and_4k, &user_version);
++    sqlite3_free(pragma_1x_and_4k);
++    if(rc == SQLITE_OK) {
++      CODEC_TRACE(("Version 1 format found\n"));
++      upgrade_1x_format = 1;
++      upgrade_4k_format = 1;
++    }
++
++    if(upgrade_1x_format == 0 && upgrade_4k_format == 0) {
++      CODEC_TRACE(("Upgrade format not determined\n"));
++      goto handle_error;
++    }
++
++    set_user_version = sqlite3_mprintf("PRAGMA migrate.user_version = %d;", user_version);
++    commands[0] = upgrade_4k_format == 1 ? pragma_4k_kdf_iter : "";
++    commands[1] = upgrade_1x_format == 1 ? pragma_hmac_off : "";
++    commands[2] = attach_command;
++    commands[3] = "SELECT sqlcipher_export('migrate');";
++    commands[4] = set_user_version;
++      
++    for(command_idx = 0; command_idx < ArraySize(commands); command_idx++){
++      const char *command = commands[command_idx];
++      if(strcmp(command, "") == 0){
++        continue;
++      }
++      rc = sqlite3_exec(db, command, NULL, NULL, NULL);
++      if(rc != SQLITE_OK){
++        break;
++      }
++    }
++    sqlite3_free(attach_command);
++    sqlite3_free(set_user_version);
++    sqlcipher_free(key, key_sz);
++    
++    if(rc == SQLITE_OK){
++      Btree *pDest;
++      Btree *pSrc;
++      int i = 0;
++
++      if( !db->autoCommit ){
++        CODEC_TRACE(("cannot migrate from within a transaction"));
++        goto handle_error;
++      }
++      if( db->nVdbeActive>1 ){
++        CODEC_TRACE(("cannot migrate - SQL statements in progress"));
++        goto handle_error;
++      }
++
++      /* Save the current value of the database flags so that it can be
++      ** restored before returning. Then set the writable-schema flag, and
++      ** disable CHECK and foreign key constraints.  */
++      saved_flags = db->flags;
++      saved_nChange = db->nChange;
++      saved_nTotalChange = db->nTotalChange;
++      saved_xTrace = db->xTrace;
++      db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin;
++      db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder);
++      db->xTrace = 0;
++      
++      pDest = db->aDb[0].pBt;
++      pDb = &(db->aDb[db->nDb-1]);
++      pSrc = pDb->pBt;
++      
++      rc = sqlite3_exec(db, "BEGIN;", NULL, NULL, NULL);
++      rc = sqlite3BtreeBeginTrans(pSrc, 2);
++      rc = sqlite3BtreeBeginTrans(pDest, 2);
++      
++      assert( 1==sqlite3BtreeIsInTrans(pDest) );
++      assert( 1==sqlite3BtreeIsInTrans(pSrc) );
++
++      sqlite3CodecGetKey(db, db->nDb - 1, (void**)&key, &password_sz);
++      sqlite3CodecAttach(db, 0, key, password_sz);
++      sqlite3pager_get_codec(pDest->pBt->pPager, (void**)&ctx);
++      
++      ctx->skip_read_hmac = 1;      
++      for(i=0; i<ArraySize(aCopy); i+=2){
++        sqlite3BtreeGetMeta(pSrc, aCopy[i], &meta);
++        rc = sqlite3BtreeUpdateMeta(pDest, aCopy[i], meta+aCopy[i+1]);
++        if( NEVER(rc!=SQLITE_OK) ) goto handle_error; 
++      }
++      rc = sqlite3BtreeCopyFile(pDest, pSrc);
++      ctx->skip_read_hmac = 0;
++      if( rc!=SQLITE_OK ) goto handle_error;
++      rc = sqlite3BtreeCommit(pDest);
++
++      db->flags = saved_flags;
++      db->nChange = saved_nChange;
++      db->nTotalChange = saved_nTotalChange;
++      db->xTrace = saved_xTrace;
++      db->autoCommit = 1;
++      if( pDb ){
++        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"));
++    }
++    
++  }
++  goto exit;
++
++ handle_error:
++  CODEC_TRACE(("An error occurred attempting to migrate the database\n"));
++  rc = SQLITE_ERROR;
++
++ exit:
++  return rc;
++}
++
++
 +#endif
 +/* END SQLCIPHER */
 +
 +/************** End of crypto_impl.c *****************************************/
 +/************** Begin file crypto_libtomcrypt.c ******************************/
- /*
--** Parse dates of the form
++/*
 +** SQLCipher
 +** http://sqlcipher.net
- **
--**     YYYY-MM-DD HH:MM:SS.FFF
--**     YYYY-MM-DD HH:MM:SS
--**     YYYY-MM-DD HH:MM
--**     YYYY-MM-DD
++**
 +** Copyright (c) 2008 - 2013, ZETETIC LLC
 +** All rights reserved.
 +**
@@ -3903,23 +3000,13 @@
 +** 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.
- **
--** 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;
++**
++*/
 +/* BEGIN SQLCIPHER */
 +#ifdef SQLITE_HAS_CODEC
 +#ifdef SQLCIPHER_CRYPTO_LIBTOMCRYPT
 +#include <tomcrypt.h>
- 
--  if( zDate[0]=='-' ){
--    zDate++;
--    neg = 1;
--  }else{
--    neg = 0;
++
 +typedef struct {
 +  prng_state prng;
 +} ltc_ctx;
@@ -3934,64 +3021,37 @@
 +
 +static int sqlcipher_ltc_activate(void *ctx) {
 +  ltc_ctx *ltc = (ltc_ctx*)ctx;
-+  int random_buffer_sz = 32;
-+  unsigned char random_buffer[random_buffer_sz];
++  int random_buffer_sz = sizeof(char) * 32;
++  unsigned char *random_buffer = sqlcipher_malloc(random_buffer_sz);
++  sqlcipher_memset(random_buffer, 0, random_buffer_sz);
 +  
 +  if(ltc_init == 0) {
 +    if(register_prng(&fortuna_desc) != CRYPT_OK) return SQLITE_ERROR;
 +    if(register_cipher(&rijndael_desc) != CRYPT_OK) return SQLITE_ERROR;
 +    if(register_hash(&sha1_desc) != CRYPT_OK) return SQLITE_ERROR;
 +    ltc_init = 1;
-   }
--  if( getDigits(zDate,4,0,9999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)!=3 ){
--    return 1;
++  }
 +  if(fortuna_start(&(ltc->prng)) != CRYPT_OK) {
 +    return SQLITE_ERROR;
-   }
--  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;
-+  sqlite3_randomness(random_buffer_sz, &random_buffer);
++  }
++  sqlite3_randomness(random_buffer_sz, random_buffer);
 +  if(sqlcipher_ltc_add_random(ctx, random_buffer, random_buffer_sz) != SQLITE_OK) {
 +    return SQLITE_ERROR;
-   }
--  p->validJD = 0;
--  p->validYMD = 1;
--  p->Y = neg ? -Y : Y;
--  p->M = M;
--  p->D = D;
--  if( p->validTZ ){
--    computeJD(p);
++  }
 +  if(sqlcipher_ltc_add_random(ctx, &ltc, sizeof(ltc_ctx*)) != SQLITE_OK) {
 +    return SQLITE_ERROR;
-   }
--  return 0;
++  }
 +  if(fortuna_ready(&(ltc->prng)) != CRYPT_OK) {
 +    return SQLITE_ERROR;
 +  }
++  sqlcipher_free(random_buffer, random_buffer_sz);
 +  return SQLITE_OK;
- }
- 
--/*
--** Set the time to the current time reported by the VFS.
--**
--** Return the number of errors.
--*/
--static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
--  sqlite3 *db = sqlite3_context_db_handle(context);
--  if( sqlite3OsCurrentTimeInt64(db->pVfs, &p->iJD)==SQLITE_OK ){
--    p->validJD = 1;
--    return 0;
--  }else{
--    return 1;
++}
++
 +static int sqlcipher_ltc_deactivate(void *ctx) {
 +  ltc_ctx *ltc = (ltc_ctx*)ctx;
 +  fortuna_done(&(ltc->prng));
++  return SQLITE_OK;
 +}
 +
 +static const char* sqlcipher_ltc_get_provider_name(void *ctx) {
@@ -4004,43 +3064,11 @@
 +  
 +  if((rc = fortuna_ready(&(ltc->prng))) != CRYPT_OK) {
 +    return SQLITE_ERROR;
-   }
++  }
 +  fortuna_read(buffer, length, &(ltc->prng));
 +  return SQLITE_OK;
- }
- 
--/*
--** 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;
++}
++
 +static int sqlcipher_ltc_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) {
 +  int rc, hash_idx;
 +  hmac_state hmac;
@@ -4054,73 +3082,34 @@
 +  return SQLITE_OK;
 +}
 +
-+static int sqlcipher_ltc_kdf(void *ctx, const char *pass, int pass_sz, unsigned char* salt, int salt_sz, 
int workfactor, int key_sz, unsigned char *key) {
++static int sqlcipher_ltc_kdf(void *ctx, const unsigned char *pass, int pass_sz, unsigned char* salt, int 
salt_sz, int workfactor, int key_sz, unsigned char *key) {
 +  int rc, hash_idx;
-+  unsigned long outlen = key_sz;
-+  unsigned long random_buffer_sz = 256;
-+  char random_buffer[random_buffer_sz];
 +  ltc_ctx *ltc = (ltc_ctx*)ctx;
++  unsigned long outlen = key_sz;
++  unsigned long random_buffer_sz = sizeof(char) * 256;
++  unsigned char *random_buffer = sqlcipher_malloc(random_buffer_sz);
++  sqlcipher_memset(random_buffer, 0, random_buffer_sz);
 +
 +  hash_idx = find_hash("sha1");
 +  if((rc = pkcs_5_alg2(pass, pass_sz, salt, salt_sz,
 +                       workfactor, hash_idx, key, &outlen)) != CRYPT_OK) {
 +    return SQLITE_ERROR;
-   }
--  return 1;
++  }
 +  if((rc = pkcs_5_alg2(key, key_sz, salt, salt_sz,
 +                       1, hash_idx, random_buffer, &random_buffer_sz)) != CRYPT_OK) {
 +    return SQLITE_ERROR;
 +  }
 +  sqlcipher_ltc_add_random(ctx, random_buffer, random_buffer_sz);
++  sqlcipher_free(random_buffer, random_buffer_sz);
 +  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;
++}
++
 +static const char* sqlcipher_ltc_get_cipher(void *ctx) {
 +  return "rijndael";
- }
- 
--/*
--** 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 int sqlcipher_ltc_cipher(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, 
unsigned char *in, int in_sz, unsigned char *out) {
-+  int rc, cipher_idx, hash_idx;
++  int rc, cipher_idx;
 +  symmetric_CBC cbc;
 +
 +  if((cipher_idx = find_cipher(sqlcipher_ltc_get_cipher(ctx))) == -1) return SQLITE_ERROR;
@@ -4129,188 +3118,48 @@
 +  if(rc != CRYPT_OK) return SQLITE_ERROR;
 +  cbc_done(&cbc);
 +  return SQLITE_OK;
- }
- 
--/*
--** Compute both YMD and HMS
--*/
--static void computeYMD_HMS(DateTime *p){
--  computeYMD(p);
--  computeHMS(p);
++}
++
 +static int sqlcipher_ltc_set_cipher(void *ctx, const char *cipher_name) {
 +  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_ltc_get_key_sz(void *ctx) {
 +  int cipher_idx = find_cipher(sqlcipher_ltc_get_cipher(ctx));
 +  return cipher_descriptor[cipher_idx].max_key_length;
- }
- 
--/*
--** 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 !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) && \
--     defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE)
--#define HAVE_LOCALTIME_S 1
--#endif
++}
++
 +static int sqlcipher_ltc_get_iv_sz(void *ctx) {
 +  int cipher_idx = find_cipher(sqlcipher_ltc_get_cipher(ctx));
 +  return cipher_descriptor[cipher_idx].block_length;
 +}
- 
--#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.
--*/
--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)
--  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 defined(HAVE_LOCALTIME_R) && 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;
++
 +static int sqlcipher_ltc_get_block_sz(void *ctx) {
 +  int cipher_idx = find_cipher(sqlcipher_ltc_get_cipher(ctx));
 +  return cipher_descriptor[cipher_idx].block_length;
- }
--#endif /* SQLITE_OMIT_LOCALTIME */
- 
++}
++
 +static int sqlcipher_ltc_get_hmac_sz(void *ctx) {
 +  int hash_idx = find_hash("sha1");
 +  return hash_descriptor[hash_idx].hashsize;
 +}
- 
--#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;
++
 +static int sqlcipher_ltc_ctx_copy(void *target_ctx, void *source_ctx) {
 +  memcpy(target_ctx, source_ctx, sizeof(ltc_ctx));
 +  return SQLITE_OK;
 +}
- 
--  /* Initialize the contents of sLocal to avoid a compiler warning. */
--  memset(&sLocal, 0, sizeof(sLocal));
++
 +static int sqlcipher_ltc_ctx_cmp(void *c1, void *c2) {
 +  return 1;
 +}
- 
--  x = *p;
--  computeYMD_HMS(&x);
--  if( x.Y<1971 || x.Y>=2038 ){
--    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;
++
 +static int sqlcipher_ltc_ctx_init(void **ctx) {
 +  *ctx = sqlcipher_malloc(sizeof(ltc_ctx));
 +  if(*ctx == NULL) return SQLITE_NOMEM;
 +  sqlcipher_ltc_activate(*ctx);
 +  return SQLITE_OK;
- }
--#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
++}
++
 +static int sqlcipher_ltc_ctx_free(void **ctx) {
 +  sqlcipher_ltc_deactivate(&ctx);
 +  sqlcipher_free(*ctx, sizeof(ltc_ctx));
@@ -4336,6 +3185,7 @@
 +  p->ctx_init = sqlcipher_ltc_ctx_init;
 +  p->ctx_free = sqlcipher_ltc_ctx_free;
 +  p->add_random = sqlcipher_ltc_add_random;
++  return SQLITE_OK;
 +}
 +
 +#endif
@@ -4372,20 +3222,8 @@
 +** 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.
- **
--** 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]];
++**
++*/
 +/* BEGIN SQLCIPHER */
 +#ifdef SQLITE_HAS_CODEC
 +#ifdef SQLCIPHER_CRYPTO_OPENSSL
@@ -4441,47 +3279,8 @@
 +  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);
-   }
--  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
 +
 +  openssl_init_count++; 
 +  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
@@ -4507,196 +3306,16 @@
 +#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
 +    sqlite3_mutex_free(openssl_rand_mutex);
 +    openssl_rand_mutex = NULL;
- #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;
++#endif
++  }
 +  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
 +  return SQLITE_OK;
- }
- 
--/*
--** 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;
++}
++
 +static const char* sqlcipher_openssl_get_provider_name(void *ctx) {
 +  return "openssl";
- }
- 
++}
++
 +/* generate a defined number of random bytes */
 +static int sqlcipher_openssl_random (void *ctx, void *buffer, int length) {
 +  int rc = 0;
@@ -4727,31 +3346,12 @@
 +  HMAC_CTX_cleanup(&hctx);
 +  return SQLITE_OK; 
 +}
- 
--/*
--** The following routines implement the various date and time functions
--** of SQLite.
--*/
-+static int sqlcipher_openssl_kdf(void *ctx, const char *pass, int pass_sz, unsigned char* salt, int 
salt_sz, int workfactor, int key_sz, unsigned char *key) {
-+  PKCS5_PBKDF2_HMAC_SHA1(pass, pass_sz, salt, salt_sz, workfactor, key_sz, key);
++
++static int sqlcipher_openssl_kdf(void *ctx, const unsigned char *pass, int pass_sz, unsigned char* salt, 
int salt_sz, int workfactor, int key_sz, unsigned char *key) {
++  PKCS5_PBKDF2_HMAC_SHA1((const char *)pass, pass_sz, salt, salt_sz, workfactor, key_sz, key);
 +  return SQLITE_OK; 
 +}
- 
--/*
--**    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);
--  }
++
 +static int sqlcipher_openssl_cipher(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, 
unsigned char *in, int in_sz, unsigned char *out) {
 +  EVP_CIPHER_CTX ectx;
 +  int tmp_csz, csz;
@@ -4767,364 +3367,56 @@
 +  EVP_CIPHER_CTX_cleanup(&ectx);
 +  assert(in_sz == csz);
 +  return SQLITE_OK; 
- }
- 
--/*
--**    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);
--  }
++}
++
 +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;
- }
- 
--/*
--**    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);
--  }
++}
++
 +static const char* sqlcipher_openssl_get_cipher(void *ctx) {
 +  return EVP_CIPHER_name(((openssl_ctx *)ctx)->evp_cipher);
- }
- 
--/*
--**    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);
--  }
++}
++
 +static int sqlcipher_openssl_get_key_sz(void *ctx) {
 +  return EVP_CIPHER_key_length(((openssl_ctx *)ctx)->evp_cipher);
- }
- 
--/*
--**    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 = (const char*)sqlite3_value_text(argv[0]);
--  char zBuf[100];
--  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);
++}
++
 +static int sqlcipher_openssl_get_iv_sz(void *ctx) {
 +  return EVP_CIPHER_iv_length(((openssl_ctx *)ctx)->evp_cipher);
- }
- 
--/*
--** 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);
++}
++
 +static int sqlcipher_openssl_get_block_sz(void *ctx) {
 +  return EVP_CIPHER_block_size(((openssl_ctx *)ctx)->evp_cipher);
- }
- 
--/*
--** 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);
++}
++
 +static int sqlcipher_openssl_get_hmac_sz(void *ctx) {
 +  return EVP_MD_size(EVP_sha1());
- }
- 
--/*
--** 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);
++}
++
 +static int sqlcipher_openssl_ctx_copy(void *target_ctx, void *source_ctx) {
 +  memcpy(target_ctx, source_ctx, sizeof(openssl_ctx));
 +  return SQLITE_OK;
- }
--#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);
++}
++
 +static int sqlcipher_openssl_ctx_cmp(void *c1, void *c2) {
 +  return ((openssl_ctx *)c1)->evp_cipher == ((openssl_ctx *)c2)->evp_cipher;
 +}
- 
--  db = sqlite3_context_db_handle(context);
--  if( sqlite3OsCurrentTimeInt64(db->pVfs, &iT) ) return;
--  t = iT/1000 - 10000*(sqlite3_int64)21086676;
--#ifdef 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);
--  }
++
 +static int sqlcipher_openssl_ctx_init(void **ctx) {
 +  *ctx = sqlcipher_malloc(sizeof(openssl_ctx));
 +  if(*ctx == NULL) return SQLITE_NOMEM;
 +  sqlcipher_openssl_activate(*ctx);
 +  return SQLITE_OK;
- }
--#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);
++}
++
 +static int sqlcipher_openssl_ctx_free(void **ctx) {
 +  sqlcipher_openssl_deactivate(*ctx);
 +  sqlcipher_free(*ctx, sizeof(openssl_ctx));
 +  return SQLITE_OK;
 +}
- 
--  for(i=0; i<ArraySize(aDateTimeFuncs); i++){
--    sqlite3FuncDefInsert(pHash, &aFunc[i]);
--  }
++
 +int sqlcipher_openssl_setup(sqlcipher_provider *p) {
 +  p->activate = sqlcipher_openssl_activate;  
 +  p->deactivate = sqlcipher_openssl_deactivate;
@@ -5145,57 +3437,18 @@
 +  p->ctx_free = sqlcipher_openssl_ctx_free;
 +  p->add_random = sqlcipher_openssl_add_random;
 +  return SQLITE_OK;
- }
- 
--/************** 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_
++}
++
 +#endif
 +#endif
 +/* END SQLCIPHER */
- 
++
 +/************** End of crypto_openssl.c **************************************/
 +/************** Begin file crypto_cc.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:
++/*
 +** SQLCipher
 +** http://sqlcipher.net
- **
--**     sqlite3OsRead()
--**     sqlite3OsWrite()
--**     sqlite3OsSync()
--**     sqlite3OsFileSize()
--**     sqlite3OsLock()
--**     sqlite3OsCheckReservedLock()
--**     sqlite3OsFileControl()
--**     sqlite3OsShmMap()
--**     sqlite3OsOpen()
--**     sqlite3OsDelete()
--**     sqlite3OsAccess()
--**     sqlite3OsFullPathname()
++**
 +** Copyright (c) 2008 - 2013, ZETETIC LLC
 +** All rights reserved.
 +**
@@ -5220,70 +3473,22 @@
 +** 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.
- **
- */
--#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
++**
++*/
 +/* BEGIN SQLCIPHER */
 +#ifdef SQLITE_HAS_CODEC
 +#ifdef SQLCIPHER_CRYPTO_CC
 +#include <CommonCrypto/CommonCrypto.h>
 +#include <Security/SecRandom.h>
- 
--/*
--** 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);
++
 +/* 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;
- }
--SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file *id, int lockType){
--  DO_OS_MALLOC_TEST(id);
--  return id->pMethods->xLock(id, lockType);
++}
 +
 +static const char* sqlcipher_cc_get_provider_name(void *ctx) {
 +  return "commoncrypto";
- }
--SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file *id, int lockType){
--  return id->pMethods->xUnlock(id, lockType);
++}
 +
 +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;
@@ -5292,27 +3497,13 @@
 +  CCHmacUpdate(&hmac_context, in2, in2_sz);
 +  CCHmacFinal(&hmac_context, out);
 +  return SQLITE_OK; 
- }
--SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
--  DO_OS_MALLOC_TEST(id);
--  return id->pMethods->xCheckReservedLock(id, pResOut);
++}
 +
-+static int sqlcipher_cc_kdf(void *ctx, const char *pass, int pass_sz, unsigned char* salt, int salt_sz, int 
workfactor, int key_sz, unsigned char *key) {
-+  CCKeyDerivationPBKDF(kCCPBKDF2, pass, pass_sz, salt, salt_sz, kCCPRFHmacAlgSHA1, workfactor, key, key_sz);
++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; 
- }
- 
--/*
--** 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){
--  DO_OS_MALLOC_TEST(id);
--  return id->pMethods->xFileControl(id, op, pArg);
++}
++
 +static int sqlcipher_cc_cipher(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, 
unsigned char *in, int in_sz, unsigned char *out) {
 +  CCCryptorRef cryptor;
 +  size_t tmp_csz, csz;
@@ -5328,81 +3519,47 @@
 +  assert(size == csz);
 +
 +  return SQLITE_OK; 
- }
--SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){
--  (void)id->pMethods->xFileControl(id, op, pArg);
++}
 +
 +static int sqlcipher_cc_set_cipher(void *ctx, const char *cipher_name) {
 +  return SQLITE_OK;
- }
- 
--SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id){
--  int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
--  return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
++}
++
 +static const char* sqlcipher_cc_get_cipher(void *ctx) {
 +  return "aes-256-cbc";
- }
--SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
--  return id->pMethods->xDeviceCharacteristics(id);
++}
 +
 +static int sqlcipher_cc_get_key_sz(void *ctx) {
 +  return kCCKeySizeAES256;
- }
--SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){
--  return id->pMethods->xShmLock(id, offset, n, flags);
++}
 +
 +static int sqlcipher_cc_get_iv_sz(void *ctx) {
 +  return kCCBlockSizeAES128;
- }
--SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id){
--  id->pMethods->xShmBarrier(id);
++}
 +
 +static int sqlcipher_cc_get_block_sz(void *ctx) {
 +  return kCCBlockSizeAES128;
- }
--SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int deleteFlag){
--  return id->pMethods->xShmUnmap(id, deleteFlag);
++}
 +
 +static int sqlcipher_cc_get_hmac_sz(void *ctx) {
 +  return CC_SHA1_DIGEST_LENGTH;
- }
--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);
++}
 +
 +static int sqlcipher_cc_ctx_copy(void *target_ctx, void *source_ctx) {
 +  return SQLITE_OK;
- }
- 
--#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);
++}
++
 +static int sqlcipher_cc_ctx_cmp(void *c1, void *c2) {
 +  return SQLITE_OK;
- }
--SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){
--  return id->pMethods->xUnfetch(id, iOff, p);
++}
 +
 +static int sqlcipher_cc_ctx_init(void **ctx) {
 +  return SQLITE_OK;
- }
--#else
--/* No-op stubs to use when memory-mapped I/O is disabled */
--SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){
--  *pp = 0;
++}
 +
 +static int sqlcipher_cc_ctx_free(void **ctx) {
-   return SQLITE_OK;
- }
--SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){
++  return SQLITE_OK;
++}
 +
 +int sqlcipher_cc_setup(sqlcipher_provider *p) {
 +  p->random = sqlcipher_cc_random;
@@ -5420,18 +3577,16 @@
 +  p->ctx_cmp = sqlcipher_cc_ctx_cmp;
 +  p->ctx_init = sqlcipher_cc_ctx_init;
 +  p->ctx_free = sqlcipher_cc_ctx_free;
-   return SQLITE_OK;
- }
++  return SQLITE_OK;
++}
 +
 +#endif
- #endif
++#endif
 +/* END SQLCIPHER */
- 
++
 +/************** End of crypto_cc.c *******************************************/
 +/************** Begin file global.c ******************************************/
- /*
--** The next group of routines are convenience wrappers around the
--** VFS methods.
++/*
 +** 2008 June 13
 +**
 +** The author disclaims copyright to this source code.  In place of
@@ -5444,194 +3599,15 @@
 +*************************************************************************
 +**
 +** This file contains definitions of global variables and contants.
- */
--SQLITE_PRIVATE int sqlite3OsOpen(
--  sqlite3_vfs *pVfs, 
--  const char *zPath, 
--  sqlite3_file *pFile, 
--  int flags, 
--  int *pFlagsOut
--){
--  int rc;
--  DO_OS_MALLOC_TEST(0);
--  /* 0x87f7f is a mask of SQLITE_OPEN_ flags that are valid to be passed
--  ** down into the VFS layer.  Some SQLITE_OPEN_ flags (for example,
--  ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before
--  ** reaching the VFS. */
--  rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x87f7f, pFlagsOut);
--  assert( rc==SQLITE_OK || pFile->pMethods==0 );
--  return rc;
--}
--SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
--  DO_OS_MALLOC_TEST(0);
--  assert( dirSync==0 || dirSync==1 );
--  return pVfs->xDelete(pVfs, zPath, dirSync);
--}
--SQLITE_PRIVATE int sqlite3OsAccess(
--  sqlite3_vfs *pVfs, 
--  const char *zPath, 
--  int flags, 
--  int *pResOut
--){
--  DO_OS_MALLOC_TEST(0);
--  return pVfs->xAccess(pVfs, zPath, flags, pResOut);
--}
--SQLITE_PRIVATE int sqlite3OsFullPathname(
--  sqlite3_vfs *pVfs, 
--  const char *zPath, 
--  int nPathOut, 
--  char *zPathOut
--){
--  DO_OS_MALLOC_TEST(0);
--  zPathOut[0] = 0;
--  return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut);
--}
--#ifndef SQLITE_OMIT_LOAD_EXTENSION
--SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
--  return pVfs->xDlOpen(pVfs, zPath);
--}
--SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
--  pVfs->xDlError(pVfs, nByte, zBufOut);
--}
--SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){
--  return pVfs->xDlSym(pVfs, pHdle, zSym);
--}
--SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
--  pVfs->xDlClose(pVfs, pHandle);
--}
--#endif /* SQLITE_OMIT_LOAD_EXTENSION */
--SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
--  return pVfs->xRandomness(pVfs, nByte, zBufOut);
--}
--SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
--  return pVfs->xSleep(pVfs, nMicro);
--}
--SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
--  int rc;
--  /* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64()
--  ** method to get the current date and time if that method is available
--  ** (if iVersion is 2 or greater and the function pointer is not NULL) and
--  ** will fall back to xCurrentTime() if xCurrentTimeInt64() is
--  ** unavailable.
--  */
--  if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){
--    rc = pVfs->xCurrentTimeInt64(pVfs, pTimeOut);
--  }else{
--    double r;
--    rc = pVfs->xCurrentTime(pVfs, &r);
--    *pTimeOut = (sqlite3_int64)(r*86400000.0);
--  }
--  return rc;
--}
--
--SQLITE_PRIVATE int sqlite3OsOpenMalloc(
--  sqlite3_vfs *pVfs, 
--  const char *zFile, 
--  sqlite3_file **ppFile, 
--  int flags,
--  int *pOutFlags
--){
--  int rc = SQLITE_NOMEM;
--  sqlite3_file *pFile;
--  pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile);
--  if( pFile ){
--    rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
--    if( rc!=SQLITE_OK ){
--      sqlite3_free(pFile);
--    }else{
--      *ppFile = pFile;
--    }
--  }
--  return rc;
--}
--SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *pFile){
--  int rc = SQLITE_OK;
--  assert( pFile );
--  rc = sqlite3OsClose(pFile);
--  sqlite3_free(pFile);
--  return rc;
--}
--
--/*
--** This function is a wrapper around the OS specific implementation of
--** sqlite3_os_init(). The purpose of the wrapper is to provide the
--** ability to simulate a malloc failure, so that the handling of an
--** error in sqlite3_os_init() by the upper layers can be tested.
--*/
--SQLITE_PRIVATE int sqlite3OsInit(void){
--  void *p = sqlite3_malloc(10);
--  if( p==0 ) return SQLITE_NOMEM;
--  sqlite3_free(p);
--  return sqlite3_os_init();
--}
--
--/*
--** The list of all registered VFS implementations.
--*/
--static sqlite3_vfs * SQLITE_WSD vfsList = 0;
--#define vfsList GLOBAL(sqlite3_vfs *, vfsList)
--
--/*
--** 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){
--  sqlite3_vfs *pVfs = 0;
--#if SQLITE_THREADSAFE
--  sqlite3_mutex *mutex;
--#endif
--#ifndef SQLITE_OMIT_AUTOINIT
--  int rc = sqlite3_initialize();
--  if( rc ) return 0;
--#endif
--#if SQLITE_THREADSAFE
--  mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
--#endif
--  sqlite3_mutex_enter(mutex);
--  for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){
--    if( zVfs==0 ) break;
--    if( strcmp(zVfs, pVfs->zName)==0 ) break;
--  }
--  sqlite3_mutex_leave(mutex);
--  return pVfs;
--}
--
--/*
--** Unlink a VFS from the linked list
--*/
--static void vfsUnlink(sqlite3_vfs *pVfs){
--  assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) );
--  if( pVfs==0 ){
--    /* No-op */
--  }else if( vfsList==pVfs ){
--    vfsList = pVfs->pNext;
--  }else if( vfsList ){
--    sqlite3_vfs *p = vfsList;
--    while( p->pNext && p->pNext!=pVfs ){
--      p = p->pNext;
--    }
--    if( p->pNext==pVfs ){
--      p->pNext = pVfs->pNext;
--    }
--  }
--}
- 
--/*
--** Register a VFS with the system.  It is harmless to register the same
--** VFS multiple times.  The new VFS becomes the default if makeDflt is
--** true.
++*/
++
 +/* An array to map all upper-case characters into their corresponding
 +** lower-case character. 
 +**
 +** 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.
- */
--SQLITE_API int 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;
++*/
 +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,
@@ -5649,28 +3625,7 @@
 +    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
--  MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
--  sqlite3_mutex_enter(mutex);
--  vfsUnlink(pVfs);
--  if( makeDflt || vfsList==0 ){
--    pVfs->pNext = vfsList;
--    vfsList = pVfs;
--  }else{
--    pVfs->pNext = vfsList->pNext;
--    vfsList->pNext = pVfs;
--  }
--  assert(vfsList);
--  sqlite3_mutex_leave(mutex);
--  return SQLITE_OK;
--}
--
--/*
--** Unregister a VFS so that it is no longer accessible.
--*/
--SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
--#if SQLITE_THREADSAFE
--  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
++#endif
 +#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 */
@@ -5688,23 +3643,13 @@
 +    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 */
- #endif
--  sqlite3_mutex_enter(mutex);
--  vfsUnlink(pVfs);
--  sqlite3_mutex_leave(mutex);
--  return SQLITE_OK;
--}
++#endif
 +};
- 
--/************** End of os.c **************************************************/
--/************** Begin file fault.c *******************************************/
- /*
--** 2008 Jan 22
++
++/*
 +** The following 256 byte lookup table is used to support SQLites built-in
 +** equivalents to the following standard library functions:
- **
--** The author disclaims copyright to this source code.  In place of
--** a legal notice, here is a blessing:
++**
 +**   isspace()                        0x01
 +**   isalpha()                        0x02
 +**   isdigit()                        0x04
@@ -5712,32 +3657,17 @@
 +**   isxdigit()                       0x08
 +**   toupper()                        0x20
 +**   SQLite identifier character      0x40
- **
--**    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.
++**
 +** Bit 0x20 is set if the mapped character requires translation to upper
 +** case. i.e. if the character is a lower-case ASCII character.
 +** If x is a lower-case ASCII character, then its upper-case equivalent
 +** is (x - 0x20). Therefore toupper() can be implemented as:
- **
--*************************************************************************
++**
 +**   (x & ~(map[x]&0x20))
- **
--** This file contains code to support the concept of "benign" 
--** malloc failures (when the xMalloc() or xRealloc() method of the
--** sqlite3_mem_methods structure fails to allocate a block of memory
--** and returns 0). 
++**
 +** Standard function tolower() is implemented using the sqlite3UpperToLower[]
 +** array. tolower() is used more often than toupper() by SQLite.
- **
--** Most malloc failures are non-benign. After they occur, SQLite
--** abandons the current operation and returns an error code (usually
--** SQLITE_NOMEM) to the user. However, sometimes a fault is not necessarily
--** fatal. For example, if a malloc fails while resizing a hash table, this 
--** is completely recoverable simply by not carrying out the resize. The 
--** hash table will continue to function normally.  So a malloc failure 
--** during a hash table resize is a benign fault.
++**
 +** Bit 0x40 is set if the character non-alphanumeric and can be used in an 
 +** SQLite identifier.  Identifiers are alphanumerics, "_", "$", and any
 +** non-ASCII UTF character. Hence the test for whether or not a character is
@@ -5745,7 +3675,7 @@
 +**
 +** 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    ........ */
@@ -5756,7 +3686,7 @@
 +  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 */
@@ -5765,17 +3695,7 @@
 +  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{|}~. */
- 
--#ifndef SQLITE_OMIT_BUILTIN_TEST
--
--/*
--** Global variables.
--*/
--typedef struct BenignMallocHooks BenignMallocHooks;
--static SQLITE_WSD struct BenignMallocHooks {
--  void (*xBenignBegin)(void);
--  void (*xBenignEnd)(void);
--} sqlite3Hooks = { 0, 0 };
++
 +  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    ........ */
@@ -5784,20 +3704,7 @@
 +  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    ........ */
- 
--/* The "wsdHooks" macro will resolve to the appropriate BenignMallocHooks
--** structure.  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, wsdHooks can refer directly
--** to the "sqlite3Hooks" state vector declared above.
--*/
--#ifdef SQLITE_OMIT_WSD
--# define wsdHooksInit \
--  BenignMallocHooks *x = &GLOBAL(BenignMallocHooks,sqlite3Hooks)
--# define wsdHooks x[0]
--#else
--# define wsdHooksInit
--# define wsdHooks sqlite3Hooks
++
 +  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    ........ */
@@ -5807,47 +3714,20 @@
 +  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* f0..f7    ........ */
 +  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40   /* f8..ff    ........ */
 +};
- #endif
- 
++#endif
++
 +#ifndef SQLITE_USE_URI
 +# define  SQLITE_USE_URI 0
 +#endif
- 
--/*
--** Register hooks to call when sqlite3BeginBenignMalloc() and
--** sqlite3EndBenignMalloc() are called, respectively.
--*/
--SQLITE_PRIVATE void sqlite3BenignMallocHooks(
--  void (*xBenignBegin)(void),
--  void (*xBenignEnd)(void)
--){
--  wsdHooksInit;
--  wsdHooks.xBenignBegin = xBenignBegin;
--  wsdHooks.xBenignEnd = xBenignEnd;
--}
++
 +#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
 +# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1
 +#endif
- 
- /*
--** This (sqlite3EndBenignMalloc()) is called by SQLite code to indicate that
--** subsequent malloc failures are benign. A call to sqlite3EndBenignMalloc()
--** indicates that subsequent malloc failures are non-benign.
++
++/*
 +** The following singleton contains the global configuration for
 +** the SQLite library.
- */
--SQLITE_PRIVATE void sqlite3BeginBenignMalloc(void){
--  wsdHooksInit;
--  if( wsdHooks.xBenignBegin ){
--    wsdHooks.xBenignBegin();
--  }
--}
--SQLITE_PRIVATE void sqlite3EndBenignMalloc(void){
--  wsdHooksInit;
--  if( wsdHooks.xBenignEnd ){
--    wsdHooks.xBenignEnd();
--  }
--}
++*/
 +SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
 +   SQLITE_DEFAULT_MEMSTATUS,  /* bMemstat */
 +   1,                         /* bCoreMutex */
@@ -5889,67 +3769,31 @@
 +   0                          /* pSqllogArg */
 +#endif
 +};
- 
--#endif   /* #ifndef SQLITE_OMIT_BUILTIN_TEST */
- 
--/************** End of fault.c ***********************************************/
--/************** Begin file mem0.c ********************************************/
- /*
--** 2008 October 28
--**
--** 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 a no-op memory allocation drivers for use when
--** SQLITE_ZERO_MALLOC is defined.  The allocation drivers implemented
--** here always fail.  SQLite will not operate with these drivers.  These
--** are merely placeholders.  Real drivers must be substituted using
--** sqlite3_config() before SQLite will operate.
++
++
++/*
 +** Hash table for global functions - functions common to all
 +** database connections.  After initialization, this table is
 +** read-only.
- */
++*/
 +SQLITE_PRIVATE SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
- 
- /*
--** This version of the memory allocator is the default.  It is
--** used when no other memory allocator is specified using compile-time
--** macros.
++
++/*
 +** Constant tokens for values 0 and 1.
- */
--#ifdef SQLITE_ZERO_MALLOC
++*/
 +SQLITE_PRIVATE const Token sqlite3IntTokens[] = {
 +   { "0", 1 },
 +   { "1", 1 }
 +};
- 
--/*
--** No-op versions of all memory allocation routines
--*/
--static void *sqlite3MemMalloc(int nByte){ return 0; }
--static void sqlite3MemFree(void *pPrior){ return; }
--static void *sqlite3MemRealloc(void *pPrior, int nByte){ return 0; }
--static int sqlite3MemSize(void *pPrior){ return 0; }
--static int sqlite3MemRoundup(int n){ return n; }
--static int sqlite3MemInit(void *NotUsed){ return SQLITE_OK; }
--static void sqlite3MemShutdown(void *NotUsed){ return; }
- 
- /*
--** This routine is the only routine in this file with external linkage.
++
++
++/*
 +** 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.
- **
--** Populate the low-level memory allocation function pointers in
--** sqlite3GlobalConfig.m with pointers to the routines in this file.
++**
 +** 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
@@ -5960,25 +3804,11 @@
 +** 0x40000000 results in an incompatible database file format!
 +** Changing the pending byte during operating results in undefined
 +** and dileterious behavior.
- */
--SQLITE_PRIVATE void sqlite3MemSetDefault(void){
--  static const sqlite3_mem_methods defaultMethods = {
--     sqlite3MemMalloc,
--     sqlite3MemFree,
--     sqlite3MemRealloc,
--     sqlite3MemSize,
--     sqlite3MemRoundup,
--     sqlite3MemInit,
--     sqlite3MemShutdown,
--     0
--  };
--  sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
--}
++*/
 +#ifndef SQLITE_OMIT_WSD
 +SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000;
 +#endif
- 
--#endif /* SQLITE_ZERO_MALLOC */
++
 +/*
 +** Properties of opcodes.  The OPFLG_INITIALIZER macro is
 +** created by mkopcodeh.awk during compilation.  Data is obtained
@@ -5986,8374 +3816,11 @@
 +** the vdbe.c file.  
 +*/
 +SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER;
- 
--/************** End of mem0.c ************************************************/
--/************** Begin file mem1.c ********************************************/
++
 +/************** End of global.c **********************************************/
 +/************** Begin file ctime.c *******************************************/
- /*
--** 2007 August 14
-+** 2010 February 23
- **
- ** The author disclaims copyright to this source code.  In place of
- ** a legal notice, here is a blessing:
-@@ -15633,807 +15866,1140 @@
- **
- *************************************************************************
- **
--** This file contains low-level memory allocation drivers for when
--** SQLite will use the standard C-library malloc/realloc/free interface
--** to obtain the memory it needs.
--**
--** This file contains implementations of the low-level memory allocation
--** routines specified in the sqlite3_mem_methods object.  The content of
--** this file is only used if SQLITE_SYSTEM_MALLOC is defined.  The
--** SQLITE_SYSTEM_MALLOC macro is defined automatically if neither the
--** SQLITE_MEMDEBUG nor the SQLITE_WIN32_MALLOC macros are defined.  The
--** default configuration is to use memory allocation routines in this
--** file.
--**
--** C-preprocessor macro summary:
--**
--**    HAVE_MALLOC_USABLE_SIZE     The configure script sets this symbol if
--**                                the malloc_usable_size() interface exists
--**                                on the target platform.  Or, this symbol
--**                                can be set manually, if desired.
--**                                If an equivalent interface exists by
--**                                a different name, using a separate -D
--**                                option to rename it.
--**
--**    SQLITE_WITHOUT_ZONEMALLOC   Some older macs lack support for the zone
--**                                memory allocator.  Set this symbol to enable
--**                                building on older macs.
--**
--**    SQLITE_WITHOUT_MSIZE        Set this symbol to disable the use of
--**                                _msize() on windows systems.  This might
--**                                be necessary when compiling for Delphi,
--**                                for example.
--*/
--
--/*
--** This version of the memory allocator is the default.  It is
--** used when no other memory allocator is specified using compile-time
--** macros.
-+** This file implements routines used to report what compile-time options
-+** SQLite was built with.
- */
--#ifdef SQLITE_SYSTEM_MALLOC
- 
--/*
--** The MSVCRT has malloc_usable_size() but it is called _msize().
--** The use of _msize() is automatic, but can be disabled by compiling
--** with -DSQLITE_WITHOUT_MSIZE
--*/
--#if defined(_MSC_VER) && !defined(SQLITE_WITHOUT_MSIZE)
--# define SQLITE_MALLOCSIZE _msize
--#endif
-+#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
- 
--#if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC)
- 
- /*
--** Use the zone allocator available on apple products unless the
--** SQLITE_WITHOUT_ZONEMALLOC symbol is defined.
-+** 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.
- */
--#include <sys/sysctl.h>
--#include <malloc/malloc.h>
--#include <libkern/OSAtomic.h>
--static malloc_zone_t* _sqliteZone_;
--#define SQLITE_MALLOC(x) malloc_zone_malloc(_sqliteZone_, (x))
--#define SQLITE_FREE(x) malloc_zone_free(_sqliteZone_, (x));
--#define SQLITE_REALLOC(x,y) malloc_zone_realloc(_sqliteZone_, (x), (y))
--#define SQLITE_MALLOCSIZE(x) \
--        (_sqliteZone_ ? _sqliteZone_->size(_sqliteZone_,x) : malloc_size(x))
-+static const char * const azCompileOpt[] = {
- 
--#else /* if not __APPLE__ */
-+/* 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)
- 
--/*
--** Use standard C library malloc and free on non-Apple systems.  
--** Also used by Apple systems if SQLITE_WITHOUT_ZONEMALLOC is defined.
--*/
--#define SQLITE_MALLOC(x)    malloc(x)
--#define SQLITE_FREE(x)      free(x)
--#define SQLITE_REALLOC(x,y) realloc((x),(y))
--
--#if (defined(_MSC_VER) && !defined(SQLITE_WITHOUT_MSIZE)) \
--      || (defined(HAVE_MALLOC_H) && defined(HAVE_MALLOC_USABLE_SIZE))
--# include <malloc.h>    /* Needed for malloc_usable_size on linux */
-+#ifdef SQLITE_32BIT_ROWID
-+  "32BIT_ROWID",
- #endif
--#ifdef HAVE_MALLOC_USABLE_SIZE
--# ifndef SQLITE_MALLOCSIZE
--#  define SQLITE_MALLOCSIZE(x) malloc_usable_size(x)
--# endif
--#else
--# undef SQLITE_MALLOCSIZE
-+#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC
-+  "4_BYTE_ALIGNED_MALLOC",
- #endif
--
--#endif /* __APPLE__ or not __APPLE__ */
-+#ifdef SQLITE_CASE_SENSITIVE_LIKE
-+  "CASE_SENSITIVE_LIKE",
-+#endif
-+#ifdef SQLITE_CHECK_PAGES
-+  "CHECK_PAGES",
-+#endif
-+#ifdef SQLITE_COVERAGE_TEST
-+  "COVERAGE_TEST",
-+#endif
-+#ifdef SQLITE_DEBUG
-+  "DEBUG",
-+#endif
-+#ifdef 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
-+  "DISABLE_DIRSYNC",
-+#endif
-+#ifdef SQLITE_DISABLE_LFS
-+  "DISABLE_LFS",
-+#endif
-+#ifdef SQLITE_ENABLE_ATOMIC_WRITE
-+  "ENABLE_ATOMIC_WRITE",
-+#endif
-+#ifdef SQLITE_ENABLE_CEROD
-+  "ENABLE_CEROD",
-+#endif
-+#ifdef SQLITE_ENABLE_COLUMN_METADATA
-+  "ENABLE_COLUMN_METADATA",
-+#endif
-+#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
-+  "ENABLE_EXPENSIVE_ASSERT",
-+#endif
-+#ifdef SQLITE_ENABLE_FTS1
-+  "ENABLE_FTS1",
-+#endif
-+#ifdef SQLITE_ENABLE_FTS2
-+  "ENABLE_FTS2",
-+#endif
-+#ifdef SQLITE_ENABLE_FTS3
-+  "ENABLE_FTS3",
-+#endif
-+#ifdef SQLITE_ENABLE_FTS3_PARENTHESIS
-+  "ENABLE_FTS3_PARENTHESIS",
-+#endif
-+#ifdef SQLITE_ENABLE_FTS4
-+  "ENABLE_FTS4",
-+#endif
-+#ifdef SQLITE_ENABLE_ICU
-+  "ENABLE_ICU",
-+#endif
-+#ifdef SQLITE_ENABLE_IOTRACE
-+  "ENABLE_IOTRACE",
-+#endif
-+#ifdef SQLITE_ENABLE_LOAD_EXTENSION
-+  "ENABLE_LOAD_EXTENSION",
-+#endif
-+#ifdef SQLITE_ENABLE_LOCKING_STYLE
-+  "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE),
-+#endif
-+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
-+  "ENABLE_MEMORY_MANAGEMENT",
-+#endif
-+#ifdef SQLITE_ENABLE_MEMSYS3
-+  "ENABLE_MEMSYS3",
-+#endif
-+#ifdef SQLITE_ENABLE_MEMSYS5
-+  "ENABLE_MEMSYS5",
-+#endif
-+#ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK
-+  "ENABLE_OVERSIZE_CELL_CHECK",
-+#endif
-+#ifdef SQLITE_ENABLE_RTREE
-+  "ENABLE_RTREE",
-+#endif
-+#ifdef SQLITE_ENABLE_STAT3
-+  "ENABLE_STAT3",
-+#endif
-+#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
-+  "ENABLE_UNLOCK_NOTIFY",
-+#endif
-+#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
-+  "ENABLE_UPDATE_DELETE_LIMIT",
-+#endif
-+#ifdef SQLITE_HAS_CODEC
-+  "HAS_CODEC",
-+#endif
-+#ifdef SQLITE_HAVE_ISNAN
-+  "HAVE_ISNAN",
-+#endif
-+#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
-+  "HOMEGROWN_RECURSIVE_MUTEX",
-+#endif
-+#ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS
-+  "IGNORE_AFP_LOCK_ERRORS",
-+#endif
-+#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
-+  "IGNORE_FLOCK_LOCK_ERRORS",
-+#endif
-+#ifdef SQLITE_INT64_TYPE
-+  "INT64_TYPE",
-+#endif
-+#ifdef 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
-+#ifdef SQLITE_MEMDEBUG
-+  "MEMDEBUG",
-+#endif
-+#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
-+  "MIXED_ENDIAN_64BIT_FLOAT",
-+#endif
-+#ifdef SQLITE_NO_SYNC
-+  "NO_SYNC",
-+#endif
-+#ifdef SQLITE_OMIT_ALTERTABLE
-+  "OMIT_ALTERTABLE",
-+#endif
-+#ifdef SQLITE_OMIT_ANALYZE
-+  "OMIT_ANALYZE",
-+#endif
-+#ifdef SQLITE_OMIT_ATTACH
-+  "OMIT_ATTACH",
-+#endif
-+#ifdef SQLITE_OMIT_AUTHORIZATION
-+  "OMIT_AUTHORIZATION",
-+#endif
-+#ifdef SQLITE_OMIT_AUTOINCREMENT
-+  "OMIT_AUTOINCREMENT",
-+#endif
-+#ifdef SQLITE_OMIT_AUTOINIT
-+  "OMIT_AUTOINIT",
-+#endif
-+#ifdef SQLITE_OMIT_AUTOMATIC_INDEX
-+  "OMIT_AUTOMATIC_INDEX",
-+#endif
-+#ifdef SQLITE_OMIT_AUTORESET
-+  "OMIT_AUTORESET",
-+#endif
-+#ifdef SQLITE_OMIT_AUTOVACUUM
-+  "OMIT_AUTOVACUUM",
-+#endif
-+#ifdef SQLITE_OMIT_BETWEEN_OPTIMIZATION
-+  "OMIT_BETWEEN_OPTIMIZATION",
-+#endif
-+#ifdef SQLITE_OMIT_BLOB_LITERAL
-+  "OMIT_BLOB_LITERAL",
-+#endif
-+#ifdef SQLITE_OMIT_BTREECOUNT
-+  "OMIT_BTREECOUNT",
-+#endif
-+#ifdef SQLITE_OMIT_BUILTIN_TEST
-+  "OMIT_BUILTIN_TEST",
-+#endif
-+#ifdef SQLITE_OMIT_CAST
-+  "OMIT_CAST",
-+#endif
-+#ifdef SQLITE_OMIT_CHECK
-+  "OMIT_CHECK",
-+#endif
-+#ifdef SQLITE_OMIT_COMPLETE
-+  "OMIT_COMPLETE",
-+#endif
-+#ifdef SQLITE_OMIT_COMPOUND_SELECT
-+  "OMIT_COMPOUND_SELECT",
-+#endif
-+#ifdef SQLITE_OMIT_DATETIME_FUNCS
-+  "OMIT_DATETIME_FUNCS",
-+#endif
-+#ifdef SQLITE_OMIT_DECLTYPE
-+  "OMIT_DECLTYPE",
-+#endif
-+#ifdef SQLITE_OMIT_DEPRECATED
-+  "OMIT_DEPRECATED",
-+#endif
-+#ifdef SQLITE_OMIT_DISKIO
-+  "OMIT_DISKIO",
-+#endif
-+#ifdef SQLITE_OMIT_EXPLAIN
-+  "OMIT_EXPLAIN",
-+#endif
-+#ifdef SQLITE_OMIT_FLAG_PRAGMAS
-+  "OMIT_FLAG_PRAGMAS",
-+#endif
-+#ifdef SQLITE_OMIT_FLOATING_POINT
-+  "OMIT_FLOATING_POINT",
-+#endif
-+#ifdef SQLITE_OMIT_FOREIGN_KEY
-+  "OMIT_FOREIGN_KEY",
-+#endif
-+#ifdef SQLITE_OMIT_GET_TABLE
-+  "OMIT_GET_TABLE",
-+#endif
-+#ifdef SQLITE_OMIT_INCRBLOB
-+  "OMIT_INCRBLOB",
-+#endif
-+#ifdef SQLITE_OMIT_INTEGRITY_CHECK
-+  "OMIT_INTEGRITY_CHECK",
-+#endif
-+#ifdef SQLITE_OMIT_LIKE_OPTIMIZATION
-+  "OMIT_LIKE_OPTIMIZATION",
-+#endif
-+#ifdef SQLITE_OMIT_LOAD_EXTENSION
-+  "OMIT_LOAD_EXTENSION",
-+#endif
-+#ifdef SQLITE_OMIT_LOCALTIME
-+  "OMIT_LOCALTIME",
-+#endif
-+#ifdef SQLITE_OMIT_LOOKASIDE
-+  "OMIT_LOOKASIDE",
-+#endif
-+#ifdef SQLITE_OMIT_MEMORYDB
-+  "OMIT_MEMORYDB",
-+#endif
-+#ifdef SQLITE_OMIT_OR_OPTIMIZATION
-+  "OMIT_OR_OPTIMIZATION",
-+#endif
-+#ifdef SQLITE_OMIT_PAGER_PRAGMAS
-+  "OMIT_PAGER_PRAGMAS",
-+#endif
-+#ifdef SQLITE_OMIT_PRAGMA
-+  "OMIT_PRAGMA",
-+#endif
-+#ifdef SQLITE_OMIT_PROGRESS_CALLBACK
-+  "OMIT_PROGRESS_CALLBACK",
-+#endif
-+#ifdef SQLITE_OMIT_QUICKBALANCE
-+  "OMIT_QUICKBALANCE",
-+#endif
-+#ifdef SQLITE_OMIT_REINDEX
-+  "OMIT_REINDEX",
-+#endif
-+#ifdef SQLITE_OMIT_SCHEMA_PRAGMAS
-+  "OMIT_SCHEMA_PRAGMAS",
-+#endif
-+#ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
-+  "OMIT_SCHEMA_VERSION_PRAGMAS",
-+#endif
-+#ifdef SQLITE_OMIT_SHARED_CACHE
-+  "OMIT_SHARED_CACHE",
-+#endif
-+#ifdef SQLITE_OMIT_SUBQUERY
-+  "OMIT_SUBQUERY",
-+#endif
-+#ifdef SQLITE_OMIT_TCL_VARIABLE
-+  "OMIT_TCL_VARIABLE",
-+#endif
-+#ifdef SQLITE_OMIT_TEMPDB
-+  "OMIT_TEMPDB",
-+#endif
-+#ifdef SQLITE_OMIT_TRACE
-+  "OMIT_TRACE",
-+#endif
-+#ifdef SQLITE_OMIT_TRIGGER
-+  "OMIT_TRIGGER",
-+#endif
-+#ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
-+  "OMIT_TRUNCATE_OPTIMIZATION",
-+#endif
-+#ifdef SQLITE_OMIT_UTF16
-+  "OMIT_UTF16",
-+#endif
-+#ifdef SQLITE_OMIT_VACUUM
-+  "OMIT_VACUUM",
-+#endif
-+#ifdef SQLITE_OMIT_VIEW
-+  "OMIT_VIEW",
-+#endif
-+#ifdef SQLITE_OMIT_VIRTUALTABLE
-+  "OMIT_VIRTUALTABLE",
-+#endif
-+#ifdef SQLITE_OMIT_WAL
-+  "OMIT_WAL",
-+#endif
-+#ifdef SQLITE_OMIT_WSD
-+  "OMIT_WSD",
-+#endif
-+#ifdef SQLITE_OMIT_XFER_OPT
-+  "OMIT_XFER_OPT",
-+#endif
-+#ifdef SQLITE_PERFORMANCE_TRACE
-+  "PERFORMANCE_TRACE",
-+#endif
-+#ifdef SQLITE_PROXY_DEBUG
-+  "PROXY_DEBUG",
-+#endif
-+#ifdef SQLITE_RTREE_INT_ONLY
-+  "RTREE_INT_ONLY",
-+#endif
-+#ifdef SQLITE_SECURE_DELETE
-+  "SECURE_DELETE",
-+#endif
-+#ifdef SQLITE_SMALL_STACK
-+  "SMALL_STACK",
-+#endif
-+#ifdef SQLITE_SOUNDEX
-+  "SOUNDEX",
-+#endif
-+#ifdef 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
-+  "TEST",
-+#endif
-+#if defined(SQLITE_THREADSAFE)
-+  "THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE),
-+#endif
-+#ifdef SQLITE_USE_ALLOCA
-+  "USE_ALLOCA",
-+#endif
-+#ifdef SQLITE_ZERO_MALLOC
-+  "ZERO_MALLOC"
-+#endif
-+};
- 
- /*
--** Like malloc(), but remember the size of the allocation
--** so that we can find it later using sqlite3MemSize().
-+** Given the name of a compile-time option, return true if that option
-+** was used and false if not.
- **
--** For this low-level routine, we are guaranteed that nByte>0 because
--** cases of nByte<=0 will be intercepted and dealt with by higher level
--** routines.
-+** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix
-+** is not required for a match.
- */
--static void *sqlite3MemMalloc(int nByte){
--#ifdef SQLITE_MALLOCSIZE
--  void *p = SQLITE_MALLOC( nByte );
--  if( p==0 ){
--    testcase( sqlite3GlobalConfig.xLog!=0 );
--    sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
--  }
--  return p;
--#else
--  sqlite3_int64 *p;
--  assert( nByte>0 );
--  nByte = ROUND8(nByte);
--  p = SQLITE_MALLOC( nByte+8 );
--  if( p ){
--    p[0] = nByte;
--    p++;
--  }else{
--    testcase( sqlite3GlobalConfig.xLog!=0 );
--    sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
-+SQLITE_API int sqlite3_compileoption_used(const char *zOptName){
-+  int i, n;
-+  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
-+     && sqlite3CtypeMap[(unsigned char)azCompileOpt[i][n]]==0
-+    ){
-+      return 1;
-+    }
-   }
--  return (void *)p;
--#endif
-+  return 0;
- }
- 
- /*
--** Like free() but works for allocations obtained from sqlite3MemMalloc()
--** or sqlite3MemRealloc().
--**
--** For this low-level routine, we already know that pPrior!=0 since
--** cases where pPrior==0 will have been intecepted and dealt with
--** by higher-level routines.
-+** Return the N-th compile-time option string.  If N is out of range,
-+** return a NULL pointer.
- */
--static void sqlite3MemFree(void *pPrior){
--#ifdef SQLITE_MALLOCSIZE
--  SQLITE_FREE(pPrior);
--#else
--  sqlite3_int64 *p = (sqlite3_int64*)pPrior;
--  assert( pPrior!=0 );
--  p--;
--  SQLITE_FREE(p);
--#endif
-+SQLITE_API const char *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 ******************************************/
- /*
--** Report the allocated size of a prior return from xMalloc()
--** or xRealloc().
-+** 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.
- */
--static int sqlite3MemSize(void *pPrior){
--#ifdef SQLITE_MALLOCSIZE
--  return pPrior ? (int)SQLITE_MALLOCSIZE(pPrior) : 0;
--#else
--  sqlite3_int64 *p;
--  if( pPrior==0 ) return 0;
--  p = (sqlite3_int64*)pPrior;
--  p--;
--  return (int)p[0];
--#endif
--}
--
-+/************** Include vdbeInt.h in the middle of status.c ******************/
-+/************** Begin file vdbeInt.h *****************************************/
- /*
--** Like realloc().  Resize an allocation previously obtained from
--** sqlite3MemMalloc().
-+** 2003 September 6
- **
--** 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
--** cases where nByte<=0 will have been intercepted by higher-level
--** routines and redirected to xFree.
-+** 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.
- */
--static void *sqlite3MemRealloc(void *pPrior, int nByte){
--#ifdef SQLITE_MALLOCSIZE
--  void *p = SQLITE_REALLOC(pPrior, nByte);
--  if( p==0 ){
--    testcase( sqlite3GlobalConfig.xLog!=0 );
--    sqlite3_log(SQLITE_NOMEM,
--      "failed memory resize %u to %u bytes",
--      SQLITE_MALLOCSIZE(pPrior), nByte);
--  }
--  return p;
--#else
--  sqlite3_int64 *p = (sqlite3_int64*)pPrior;
--  assert( pPrior!=0 && nByte>0 );
--  assert( nByte==ROUND8(nByte) ); /* EV: R-46199-30249 */
--  p--;
--  p = SQLITE_REALLOC(p, nByte+8 );
--  if( p ){
--    p[0] = nByte;
--    p++;
--  }else{
--    testcase( sqlite3GlobalConfig.xLog!=0 );
--    sqlite3_log(SQLITE_NOMEM,
--      "failed memory resize %u to %u bytes",
--      sqlite3MemSize(pPrior), nByte);
--  }
--  return (void*)p;
-+#ifndef _VDBEINT_H_
-+#define _VDBEINT_H_
-+
 +/*
-+** 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
--}
- 
- /*
--** Round up a request size to the next valid allocation size.
-+** SQL is translated into a sequence of instructions to be
-+** executed by a virtual machine.  Each instruction is an instance
-+** of the following structure.
- */
--static int sqlite3MemRoundup(int n){
--  return ROUND8(n);
--}
-+typedef struct VdbeOp Op;
- 
- /*
--** Initialize this module.
-+** Boolean values
- */
--static int sqlite3MemInit(void *NotUsed){
--#if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC)
--  int cpuCount;
--  size_t len;
--  if( _sqliteZone_ ){
--    return SQLITE_OK;
--  }
--  len = sizeof(cpuCount);
--  /* One usually wants to use hw.acctivecpu for MT decisions, but not here */
--  sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0);
--  if( cpuCount>1 ){
--    /* defer MT decisions to system malloc */
--    _sqliteZone_ = malloc_default_zone();
--  }else{
--    /* only 1 core, use our own zone to contention over global locks, 
--    ** e.g. we have our own dedicated locks */
--    bool success;
--    malloc_zone_t* newzone = malloc_create_zone(4096, 0);
--    malloc_set_zone_name(newzone, "Sqlite_Heap");
--    do{
--      success = OSAtomicCompareAndSwapPtrBarrier(NULL, newzone, 
--                                 (void * volatile *)&_sqliteZone_);
--    }while(!_sqliteZone_);
--    if( !success ){
--      /* somebody registered a zone first */
--      malloc_destroy_zone(newzone);
--    }
--  }
--#endif
--  UNUSED_PARAMETER(NotUsed);
--  return SQLITE_OK;
--}
-+typedef unsigned char Bool;
- 
--/*
--** Deinitialize this module.
--*/
--static void sqlite3MemShutdown(void *NotUsed){
--  UNUSED_PARAMETER(NotUsed);
--  return;
--}
-+/* Opaque type used by code in vdbesort.c */
-+typedef struct VdbeSorter VdbeSorter;
-+
-+/* Opaque type used by the explainer */
-+typedef struct Explain Explain;
- 
- /*
--** This routine is the only routine in this file with external linkage.
--**
--** Populate the low-level memory allocation function pointers in
--** sqlite3GlobalConfig.m with pointers to the routines in this file.
-+** 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.
-+** 
-+** Every cursor that the virtual machine has open is represented by an
-+** instance of the following structure.
- */
--SQLITE_PRIVATE void sqlite3MemSetDefault(void){
--  static const sqlite3_mem_methods defaultMethods = {
--     sqlite3MemMalloc,
--     sqlite3MemFree,
--     sqlite3MemRealloc,
--     sqlite3MemSize,
--     sqlite3MemRoundup,
--     sqlite3MemInit,
--     sqlite3MemShutdown,
--     0
--  };
--  sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
--}
-+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 iDb;              /* Index of cursor database in db->aDb[] (or -1) */
-+  int pseudoTableReg;   /* Register holding pseudotable content. */
-+  int nField;           /* Number of fields in the header */
-+  Bool zeroed;          /* True if zeroed out and ready for reuse */
-+  Bool rowidIsValid;    /* True if lastRowid is valid */
-+  Bool atFirst;         /* True if pointing to first entry */
-+  Bool useRandomRowid;  /* Generate new record numbers semi-randomly */
-+  Bool nullRow;         /* True if pointing to a row with no data */
-+  Bool deferredMoveto;  /* A call to sqlite3BtreeMoveto() is needed */
-+  Bool isTable;         /* True if a table requiring integer keys */
-+  Bool isIndex;         /* True if an index containing keys only - no data */
-+  Bool isOrdered;       /* True if the underlying table is BTREE_UNORDERED */
-+  Bool isSorter;        /* True if a new-style sorter */
-+  Bool multiPseudo;     /* Multi-register pseudo-cursor */
-+  sqlite3_vtab_cursor *pVtabCursor;  /* The cursor for a virtual table */
-+  const sqlite3_module *pModule;     /* Module for cursor pVtabCursor */
-+  i64 seqCount;         /* Sequence counter */
-+  i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
-+  i64 lastRowid;        /* Last rowid from a Next or NextIdx operation */
-+  VdbeSorter *pSorter;  /* Sorter object for OP_SorterOpen cursors */
- 
--#endif /* SQLITE_SYSTEM_MALLOC */
-+  /* Result of last sqlite3BtreeMoveto() done by an OP_NotExists or 
-+  ** OP_IsUnique opcode on this cursor. */
-+  int seekResult;
-+
-+  /* 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 */
-+  int payloadSize;      /* Total number of bytes in the record */
-+  u32 *aType;           /* Type values for all entries in the record */
-+  u32 *aOffset;         /* Cached offsets to the start of each columns data */
-+  u8 *aRow;             /* Data for the current row, if all on one page */
-+};
-+typedef struct VdbeCursor VdbeCursor;
- 
--/************** End of mem1.c ************************************************/
--/************** Begin file mem2.c ********************************************/
- /*
--** 2007 August 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.
--**
--*************************************************************************
-+** 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.
- **
--** This file contains low-level memory allocation drivers for when
--** SQLite will use the standard C-library malloc/realloc/free interface
--** to obtain the memory it needs while adding lots of additional debugging
--** information to each allocation in order to help detect and fix memory
--** leaks and memory usage errors.
-+** 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.
- **
--** This file contains implementations of the low-level memory allocation
--** routines specified in the sqlite3_mem_methods object.
-+** 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 */
-+  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.nChanges)     */
-+};
-+
-+#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
- 
- /*
--** This version of the memory allocator is used only if the
--** SQLITE_MEMDEBUG macro is defined
-+** A value for VdbeCursor.cacheValid that means the cache is always invalid.
- */
--#ifdef SQLITE_MEMDEBUG
-+#define CACHE_STALE 0
- 
- /*
--** The backtrace functionality is only available with GLIBC
-+** 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.
- */
--#ifdef __GLIBC__
--  extern int backtrace(void**,int);
--  extern void backtrace_symbols_fd(void*const*,int,int);
--#else
--# define backtrace(A,B) 1
--# define backtrace_symbols_fd(A,B,C)
-+struct Mem {
-+  sqlite3 *db;        /* The associated database connection */
-+  char *z;            /* String or BLOB value */
-+  double r;           /* Real value */
-+  union {
-+    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  type;           /* One of SQLITE_NULL, SQLITE_TEXT, SQLITE_INTEGER, etc */
-+  u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
-+#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
--/* #include <stdio.h> */
-+  void (*xDel)(void *);  /* If not null, call this function to delete Mem.z */
-+  char *zMalloc;      /* Dynamic buffer allocated by sqlite3_malloc() */
-+};
- 
--/*
--** Each memory allocation looks like this:
-+/* One or more of the following flags are set to indicate the validOK
-+** representations of the value stored in the Mem struct.
- **
--**  ------------------------------------------------------------------------
--**  | Title |  backtrace pointers |  MemBlockHdr |  allocation |  EndGuard |
--**  ------------------------------------------------------------------------
-+** If the MEM_Null flag is set, then the value is an SQL NULL value.
-+** No other flags may be set in this case.
- **
--** The application code sees only a pointer to the allocation.  We have
--** to back up from the allocation pointer to find the MemBlockHdr.  The
--** MemBlockHdr tells us the size of the allocation and the number of
--** backtrace pointers.  There is also a guard word at the end of the
--** MemBlockHdr.
-+** 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.
- */
--struct MemBlockHdr {
--  i64 iSize;                          /* Size of this allocation */
--  struct MemBlockHdr *pNext, *pPrev;  /* Linked list of all unfreed memory */
--  char nBacktrace;                    /* Number of backtraces on this alloc */
--  char nBacktraceSlots;               /* Available backtrace slots */
--  u8 nTitle;                          /* Bytes of title; includes '\0' */
--  u8 eType;                           /* Allocation type code */
--  int iForeGuard;                     /* Guard word for sanity */
--};
-+#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_RowSet    0x0020   /* Value is a RowSet object */
-+#define MEM_Frame     0x0040   /* Value is a VdbeFrame object */
-+#define MEM_Invalid   0x0080   /* Value is undefined */
-+#define MEM_Cleared   0x0100   /* NULL set by OP_Null, not from data */
-+#define MEM_TypeMask  0x01ff   /* Mask of type bits */
- 
--/*
--** Guard words
-+
-+/* 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 FOREGUARD 0x80F5E153
--#define REARGUARD 0xE4676B53
-+#define MEM_Term      0x0200   /* String rep is nul terminated */
-+#define MEM_Dyn       0x0400   /* Need to call sqliteFree() 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
- 
- /*
--** Number of malloc size increments to track.
-+** Clear any existing type flags from a Mem and replace them with f
- */
--#define NCSIZE  1000
-+#define MemSetTypeFlag(p, f) \
-+   ((p)->flags = ((p)->flags&~(MEM_TypeMask|MEM_Zero))|f)
- 
- /*
--** All of the static variables used by this module are collected
--** into a single structure named "mem".  This is to keep the
--** static variables organized and to reduce namespace pollution
--** when this module is combined with other in the amalgamation.
-+** Return true if a memory cell is not marked as invalid.  This macro
-+** is for use inside assert() statements only.
- */
--static struct {
--  
--  /*
--  ** Mutex to control access to the memory allocation subsystem.
--  */
--  sqlite3_mutex *mutex;
--
--  /*
--  ** Head and tail of a linked list of all outstanding allocations
--  */
--  struct MemBlockHdr *pFirst;
--  struct MemBlockHdr *pLast;
--  
--  /*
--  ** The number of levels of backtrace to save in new allocations.
--  */
--  int nBacktrace;
--  void (*xBacktrace)(int, int, void **);
--
--  /*
--  ** Title text to insert in front of each block
--  */
--  int nTitle;        /* Bytes of zTitle to save.  Includes '\0' and padding */
--  char zTitle[100];  /* The title text */
--
--  /* 
--  ** sqlite3MallocDisallow() increments the following counter.
--  ** sqlite3MallocAllow() decrements it.
--  */
--  int disallow; /* Do not allow memory allocation */
--
--  /*
--  ** Gather statistics on the sizes of memory allocations.
--  ** nAlloc[i] is the number of allocation attempts of i*8
--  ** bytes.  i==NCSIZE is the number of allocation attempts for
--  ** sizes more than NCSIZE*8 bytes.
--  */
--  int nAlloc[NCSIZE];      /* Total number of allocations */
--  int nCurrent[NCSIZE];    /* Current number of allocations */
--  int mxCurrent[NCSIZE];   /* Highwater mark for nCurrent */
--
--} mem;
-+#ifdef SQLITE_DEBUG
-+#define memIsValid(M)  ((M)->flags & MEM_Invalid)==0
-+#endif
- 
- 
--/*
--** Adjust memory usage statistics
-+/* A VdbeFunc is just a FuncDef (defined in sqliteInt.h) that contains
-+** additional information about auxiliary information bound to arguments
-+** of the function.  This is used to implement the sqlite3_get_auxdata()
-+** and sqlite3_set_auxdata() APIs.  The "auxdata" is some auxiliary data
-+** that can be associated with a constant argument to a function.  This
-+** allows functions such as "regexp" to compile their constant regular
-+** expression argument once and reused the compiled code for multiple
-+** invocations.
- */
--static void adjustStats(int iSize, int increment){
--  int i = ROUND8(iSize)/8;
--  if( i>NCSIZE-1 ){
--    i = NCSIZE - 1;
--  }
--  if( increment>0 ){
--    mem.nAlloc[i]++;
--    mem.nCurrent[i]++;
--    if( mem.nCurrent[i]>mem.mxCurrent[i] ){
--      mem.mxCurrent[i] = mem.nCurrent[i];
--    }
--  }else{
--    mem.nCurrent[i]--;
--    assert( mem.nCurrent[i]>=0 );
--  }
--}
-+struct VdbeFunc {
-+  FuncDef *pFunc;               /* The definition of the function */
-+  int nAux;                     /* Number of entries allocated for apAux[] */
-+  struct AuxData {
-+    void *pAux;                   /* Aux data for the i-th argument */
-+    void (*xDelete)(void *);      /* Destructor for the aux data */
-+  } apAux[1];                   /* One slot for each function argument */
-+};
- 
- /*
--** Given an allocation, find the MemBlockHdr for that allocation.
-+** The "context" argument for a installable function.  A pointer to an
-+** instance of this structure is the first argument to the routines used
-+** implement the SQL functions.
- **
--** This routine checks the guards at either end of the allocation and
--** if they are incorrect it asserts.
-+** 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.
- */
--static struct MemBlockHdr *sqlite3MemsysGetHeader(void *pAllocation){
--  struct MemBlockHdr *p;
--  int *pInt;
--  u8 *pU8;
--  int nReserve;
--
--  p = (struct MemBlockHdr*)pAllocation;
--  p--;
--  assert( p->iForeGuard==(int)FOREGUARD );
--  nReserve = ROUND8(p->iSize);
--  pInt = (int*)pAllocation;
--  pU8 = (u8*)pAllocation;
--  assert( pInt[nReserve/sizeof(int)]==(int)REARGUARD );
--  /* This checks any of the "extra" bytes allocated due
--  ** to rounding up to an 8 byte boundary to ensure 
--  ** they haven't been overwritten.
--  */
--  while( nReserve-- > p->iSize ) assert( pU8[nReserve]==0x65 );
--  return p;
--}
-+struct sqlite3_context {
-+  FuncDef *pFunc;       /* Pointer to function information.  MUST BE FIRST */
-+  VdbeFunc *pVdbeFunc;  /* Auxilary data, if created. */
-+  Mem s;                /* The return value is stored here */
-+  Mem *pMem;            /* Memory cell used to store aggregate context */
-+  CollSeq *pColl;       /* Collating sequence */
-+  int isError;          /* Error code returned by the function. */
-+  int skipFlag;         /* Skip skip accumulator loading if true */
-+};
- 
- /*
--** Return the number of bytes currently allocated at address p.
-+** An Explain object accumulates indented output which is helpful
-+** in describing recursive data structures.
- */
--static int sqlite3MemSize(void *p){
--  struct MemBlockHdr *pHdr;
--  if( !p ){
--    return 0;
--  }
--  pHdr = sqlite3MemsysGetHeader(p);
--  return pHdr->iSize;
--}
-+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 */
-+};
- 
--/*
--** Initialize the memory allocation subsystem.
-+/* A bitfield type for use inside of structures.  Always follow with :N where
-+** N is the number of bits.
- */
--static int sqlite3MemInit(void *NotUsed){
--  UNUSED_PARAMETER(NotUsed);
--  assert( (sizeof(struct MemBlockHdr)&7) == 0 );
--  if( !sqlite3GlobalConfig.bMemstat ){
--    /* If memory status is enabled, then the malloc.c wrapper will already
--    ** hold the STATIC_MEM mutex when the routines here are invoked. */
--    mem.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
--  }
--  return SQLITE_OK;
--}
-+typedef unsigned bft;  /* Bit Field Type */
- 
- /*
--** Deinitialize the memory allocation subsystem.
-+** 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.
- */
--static void sqlite3MemShutdown(void *NotUsed){
--  UNUSED_PARAMETER(NotUsed);
--  mem.mutex = 0;
--}
-+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 */
-+  int nMem;               /* Number of memory locations currently allocated */
-+  int nOp;                /* Number of instructions in the program */
-+  int nOpAlloc;           /* Number of slots allocated for aOp[] */
-+  int nLabel;             /* Number of labels used */
-+  int *aLabel;            /* Space to hold the labels */
-+  u16 nResColumn;         /* Number of columns in one row of the result set */
-+  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 */
-+  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 */
-+  bft usesStmtJournal:1;  /* True if uses a statement journal */
-+  bft readOnly:1;         /* True for read-only statements */
-+  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) */
-+  int aCounter[3];        /* Counters used by sqlite3_stmt_status() */
-+#ifndef SQLITE_OMIT_TRACE
-+  i64 startTime;          /* Time when query started - used for profiling */
-+#endif
-+  i64 nFkConstraint;      /* Number of imm. FK constraints this VM */
-+  i64 nStmtDefCons;       /* Number of def. constraints when stmt started */
-+  char *zSql;             /* Text of the SQL statement that generated this */
-+  void *pFree;            /* Free this when deleting the vdbe */
-+#ifdef SQLITE_DEBUG
-+  FILE *trace;            /* Write an execution trace here, if not NULL */
-+#endif
-+#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 */
-+  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 */
-+};
- 
- /*
--** Round up a request size to the next valid allocation size.
-+** The following are allowed values for Vdbe.magic
- */
--static int sqlite3MemRoundup(int n){
--  return ROUND8(n);
--}
-+#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 */
- 
- /*
--** Fill a buffer with pseudo-random bytes.  This is used to preset
--** the content of a new memory allocation to unpredictable values and
--** to clear the content of a freed allocation to unpredictable values.
-+** Function prototypes
- */
--static void randomFill(char *pBuf, int nByte){
--  unsigned int x, y, r;
--  x = SQLITE_PTR_TO_INT(pBuf);
--  y = nByte | 1;
--  while( nByte >= 4 ){
--    x = (x>>1) ^ (-(x&1) & 0xd0000001);
--    y = y*1103515245 + 12345;
--    r = x ^ y;
--    *(int*)pBuf = r;
--    pBuf += 4;
--    nByte -= 4;
--  }
--  while( nByte-- > 0 ){
--    x = (x>>1) ^ (-(x&1) & 0xd0000001);
--    y = y*1103515245 + 12345;
--    r = x ^ y;
--    *(pBuf++) = r & 0xff;
--  }
--}
-+SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
-+void sqliteVdbePopStack(Vdbe*,int);
-+SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(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*, int, Mem*, int);
-+SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
-+SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);
- 
--/*
--** Allocate nByte bytes of memory.
--*/
--static void *sqlite3MemMalloc(int nByte){
--  struct MemBlockHdr *pHdr;
--  void **pBt;
--  char *z;
--  int *pInt;
--  void *p = 0;
--  int totalSize;
--  int nReserve;
--  sqlite3_mutex_enter(mem.mutex);
--  assert( mem.disallow==0 );
--  nReserve = ROUND8(nByte);
--  totalSize = nReserve + sizeof(*pHdr) + sizeof(int) +
--               mem.nBacktrace*sizeof(void*) + mem.nTitle;
--  p = malloc(totalSize);
--  if( p ){
--    z = p;
--    pBt = (void**)&z[mem.nTitle];
--    pHdr = (struct MemBlockHdr*)&pBt[mem.nBacktrace];
--    pHdr->pNext = 0;
--    pHdr->pPrev = mem.pLast;
--    if( mem.pLast ){
--      mem.pLast->pNext = pHdr;
--    }else{
--      mem.pFirst = pHdr;
--    }
--    mem.pLast = pHdr;
--    pHdr->iForeGuard = FOREGUARD;
--    pHdr->eType = MEMTYPE_HEAP;
--    pHdr->nBacktraceSlots = mem.nBacktrace;
--    pHdr->nTitle = mem.nTitle;
--    if( mem.nBacktrace ){
--      void *aAddr[40];
--      pHdr->nBacktrace = backtrace(aAddr, mem.nBacktrace+1)-1;
--      memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*));
--      assert(pBt[0]);
--      if( mem.xBacktrace ){
--        mem.xBacktrace(nByte, pHdr->nBacktrace-1, &aAddr[1]);
--      }
--    }else{
--      pHdr->nBacktrace = 0;
--    }
--    if( mem.nTitle ){
--      memcpy(z, mem.zTitle, mem.nTitle);
--    }
--    pHdr->iSize = nByte;
--    adjustStats(nByte, +1);
--    pInt = (int*)&pHdr[1];
--    pInt[nReserve/sizeof(int)] = REARGUARD;
--    randomFill((char*)pInt, nByte);
--    memset(((char*)pInt)+nByte, 0x65, nReserve-nByte);
--    p = (void*)pInt;
--  }
--  sqlite3_mutex_leave(mem.mutex);
--  return p; 
--}
-+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 sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
-+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 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 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 int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
-+SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
-+SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p);
-+#define VdbeMemRelease(X)  \
-+  if((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame)) \
-+    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 sqlite3VdbeCloseStatement(Vdbe *, int);
-+SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*);
-+SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *);
-+SQLITE_PRIVATE void sqlite3VdbeMemStoreType(Mem *pMem);
-+SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p);
-+
-+SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *);
-+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 sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, 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*);
-+#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 *********************/
- 
- /*
--** Free memory.
-+** Variables in which to record status information.
- */
--static void sqlite3MemFree(void *pPrior){
--  struct MemBlockHdr *pHdr;
--  void **pBt;
--  char *z;
--  assert( sqlite3GlobalConfig.bMemstat || sqlite3GlobalConfig.bCoreMutex==0 
--       || mem.mutex!=0 );
--  pHdr = sqlite3MemsysGetHeader(pPrior);
--  pBt = (void**)pHdr;
--  pBt -= pHdr->nBacktraceSlots;
--  sqlite3_mutex_enter(mem.mutex);
--  if( pHdr->pPrev ){
--    assert( pHdr->pPrev->pNext==pHdr );
--    pHdr->pPrev->pNext = pHdr->pNext;
--  }else{
--    assert( mem.pFirst==pHdr );
--    mem.pFirst = pHdr->pNext;
--  }
--  if( pHdr->pNext ){
--    assert( pHdr->pNext->pPrev==pHdr );
--    pHdr->pNext->pPrev = pHdr->pPrev;
--  }else{
--    assert( mem.pLast==pHdr );
--    mem.pLast = pHdr->pPrev;
--  }
--  z = (char*)pBt;
--  z -= pHdr->nTitle;
--  adjustStats(pHdr->iSize, -1);
--  randomFill(z, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) +
--                pHdr->iSize + sizeof(int) + pHdr->nTitle);
--  free(z);
--  sqlite3_mutex_leave(mem.mutex);  
--}
-+typedef struct sqlite3StatType sqlite3StatType;
-+static SQLITE_WSD struct sqlite3StatType {
-+  int nowValue[10];         /* Current value */
-+  int mxValue[10];          /* Maximum value */
-+} sqlite3Stat = { {0,}, {0,} };
- 
--/*
--** Change the size of an existing memory allocation.
--**
--** For this debugging implementation, we *always* make a copy of the
--** allocation into a new place in memory.  In this way, if the 
--** higher level code is using pointer to the old allocation, it is 
--** much more likely to break and we are much more liking to find
--** the error.
-+
-+/* 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.
- */
--static void *sqlite3MemRealloc(void *pPrior, int nByte){
--  struct MemBlockHdr *pOldHdr;
--  void *pNew;
--  assert( mem.disallow==0 );
--  assert( (nByte & 7)==0 );     /* EV: R-46199-30249 */
--  pOldHdr = sqlite3MemsysGetHeader(pPrior);
--  pNew = sqlite3MemMalloc(nByte);
--  if( pNew ){
--    memcpy(pNew, pPrior, nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize);
--    if( nByte>pOldHdr->iSize ){
--      randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - pOldHdr->iSize);
--    }
--    sqlite3MemFree(pPrior);
--  }
--  return pNew;
--}
-+#ifdef SQLITE_OMIT_WSD
-+# define wsdStatInit  sqlite3StatType *x = &GLOBAL(sqlite3StatType,sqlite3Stat)
-+# define wsdStat x[0]
-+#else
-+# define wsdStatInit
-+# define wsdStat sqlite3Stat
-+#endif
- 
- /*
--** Populate the low-level memory allocation function pointers in
--** sqlite3GlobalConfig.m with pointers to the routines in this file.
-+** Return the current value of a status parameter.
- */
--SQLITE_PRIVATE void sqlite3MemSetDefault(void){
--  static const sqlite3_mem_methods defaultMethods = {
--     sqlite3MemMalloc,
--     sqlite3MemFree,
--     sqlite3MemRealloc,
--     sqlite3MemSize,
--     sqlite3MemRoundup,
--     sqlite3MemInit,
--     sqlite3MemShutdown,
--     0
--  };
--  sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
-+SQLITE_PRIVATE int sqlite3StatusValue(int op){
-+  wsdStatInit;
-+  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
-+  return wsdStat.nowValue[op];
- }
- 
- /*
--** Set the "type" of an allocation.
-+** Add N to the value of a status record.  It is assumed that the
-+** caller holds appropriate locks.
- */
--SQLITE_PRIVATE void sqlite3MemdebugSetType(void *p, u8 eType){
--  if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
--    struct MemBlockHdr *pHdr;
--    pHdr = sqlite3MemsysGetHeader(p);
--    assert( pHdr->iForeGuard==FOREGUARD );
--    pHdr->eType = eType;
-+SQLITE_PRIVATE void sqlite3StatusAdd(int op, int N){
-+  wsdStatInit;
-+  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
-+  wsdStat.nowValue[op] += N;
-+  if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
-+    wsdStat.mxValue[op] = wsdStat.nowValue[op];
-   }
- }
- 
- /*
--** Return TRUE if the mask of type in eType matches the type of the
--** allocation p.  Also return true if p==NULL.
--**
--** This routine is designed for use within an assert() statement, to
--** verify the type of an allocation.  For example:
--**
--**     assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
-+** Set the value of a status to X.
- */
--SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){
--  int rc = 1;
--  if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
--    struct MemBlockHdr *pHdr;
--    pHdr = sqlite3MemsysGetHeader(p);
--    assert( pHdr->iForeGuard==FOREGUARD );         /* Allocation is valid */
--    if( (pHdr->eType&eType)==0 ){
--      rc = 0;
--    }
-+SQLITE_PRIVATE void sqlite3StatusSet(int op, int X){
-+  wsdStatInit;
-+  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
-+  wsdStat.nowValue[op] = X;
-+  if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
-+    wsdStat.mxValue[op] = wsdStat.nowValue[op];
-   }
--  return rc;
- }
- 
- /*
--** Return TRUE if the mask of type in eType matches no bits of the type of the
--** allocation p.  Also return true if p==NULL.
--**
--** This routine is designed for use within an assert() statement, to
--** verify the type of an allocation.  For example:
-+** Query status information.
- **
--**     assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
-+** 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_PRIVATE int sqlite3MemdebugNoType(void *p, u8 eType){
--  int rc = 1;
--  if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
--    struct MemBlockHdr *pHdr;
--    pHdr = sqlite3MemsysGetHeader(p);
--    assert( pHdr->iForeGuard==FOREGUARD );         /* Allocation is valid */
--    if( (pHdr->eType&eType)!=0 ){
--      rc = 0;
--    }
-+SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
-+  wsdStatInit;
-+  if( op<0 || op>=ArraySize(wsdStat.nowValue) ){
-+    return SQLITE_MISUSE_BKPT;
-   }
--  return rc;
--}
--
--/*
--** Set the number of backtrace levels kept for each allocation.
--** A value of zero turns off backtracing.  The number is always rounded
--** up to a multiple of 2.
--*/
--SQLITE_PRIVATE void sqlite3MemdebugBacktrace(int depth){
--  if( depth<0 ){ depth = 0; }
--  if( depth>20 ){ depth = 20; }
--  depth = (depth+1)&0xfe;
--  mem.nBacktrace = depth;
--}
--
--SQLITE_PRIVATE void sqlite3MemdebugBacktraceCallback(void (*xBacktrace)(int, int, void **)){
--  mem.xBacktrace = xBacktrace;
--}
--
--/*
--** Set the title string for subsequent allocations.
--*/
--SQLITE_PRIVATE void sqlite3MemdebugSettitle(const char *zTitle){
--  unsigned int n = sqlite3Strlen30(zTitle) + 1;
--  sqlite3_mutex_enter(mem.mutex);
--  if( n>=sizeof(mem.zTitle) ) n = sizeof(mem.zTitle)-1;
--  memcpy(mem.zTitle, zTitle, n);
--  mem.zTitle[n] = 0;
--  mem.nTitle = ROUND8(n);
--  sqlite3_mutex_leave(mem.mutex);
--}
--
--SQLITE_PRIVATE void sqlite3MemdebugSync(){
--  struct MemBlockHdr *pHdr;
--  for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){
--    void **pBt = (void**)pHdr;
--    pBt -= pHdr->nBacktraceSlots;
--    mem.xBacktrace(pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]);
-+  *pCurrent = wsdStat.nowValue[op];
-+  *pHighwater = wsdStat.mxValue[op];
-+  if( resetFlag ){
-+    wsdStat.mxValue[op] = wsdStat.nowValue[op];
-   }
-+  return SQLITE_OK;
- }
- 
- /*
--** Open the file indicated and write a log of all unfreed memory 
--** allocations into that log.
-+** Query status information for a single database connection
- */
--SQLITE_PRIVATE void sqlite3MemdebugDump(const char *zFilename){
--  FILE *out;
--  struct MemBlockHdr *pHdr;
--  void **pBt;
--  int i;
--  out = fopen(zFilename, "w");
--  if( out==0 ){
--    fprintf(stderr, "** Unable to output memory debug output log: %s **\n",
--                    zFilename);
--    return;
--  }
--  for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){
--    char *z = (char*)pHdr;
--    z -= pHdr->nBacktraceSlots*sizeof(void*) + pHdr->nTitle;
--    fprintf(out, "**** %lld bytes at %p from %s ****\n", 
--            pHdr->iSize, &pHdr[1], pHdr->nTitle ? z : "???");
--    if( pHdr->nBacktrace ){
--      fflush(out);
--      pBt = (void**)pHdr;
--      pBt -= pHdr->nBacktraceSlots;
--      backtrace_symbols_fd(pBt, pHdr->nBacktrace, fileno(out));
--      fprintf(out, "\n");
-+SQLITE_API int 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 */
-+  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;
-     }
--  }
--  fprintf(out, "COUNTS:\n");
--  for(i=0; i<NCSIZE-1; i++){
--    if( mem.nAlloc[i] ){
--      fprintf(out, "   %5d: %10d %10d %10d\n", 
--            i*8, mem.nAlloc[i], mem.nCurrent[i], mem.mxCurrent[i]);
-+
-+    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;
-     }
--  }
--  if( mem.nAlloc[NCSIZE-1] ){
--    fprintf(out, "   %5d: %10d %10d %10d\n",
--             NCSIZE*8-8, mem.nAlloc[NCSIZE-1],
--             mem.nCurrent[NCSIZE-1], mem.mxCurrent[NCSIZE-1]);
--  }
--  fclose(out);
--}
- 
--/*
--** Return the number of times sqlite3MemMalloc() has been called.
--*/
--SQLITE_PRIVATE int sqlite3MemdebugMallocCount(){
--  int i;
--  int nTotal = 0;
--  for(i=0; i<NCSIZE; i++){
--    nTotal += mem.nAlloc[i];
--  }
--  return nTotal;
--}
-+    /* 
-+    ** 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 */
- 
--#endif /* SQLITE_MEMDEBUG */
-+      sqlite3BtreeEnterAll(db);
-+      db->pnBytesFreed = &nByte;
-+      for(i=0; i<db->nDb; i++){
-+        Schema *pSchema = db->aDb[i].pSchema;
-+        if( ALWAYS(pSchema!=0) ){
-+          HashElem *p;
- 
--/************** End of mem2.c ************************************************/
--/************** Begin file mem3.c ********************************************/
--/*
--** 2007 October 14
-+          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;
-+      *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;
-+      *pCurrent = nRet;
-+      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:
-@@ -16443,1269 +17009,1505 @@
- **    May you share freely, never taking more than you give.
- **
- *************************************************************************
--** This file contains the C functions that implement a memory
--** allocation subsystem for use by SQLite. 
-+** This file contains the C functions that implement date and time
-+** functions for SQLite.  
- **
--** This version of the memory allocation subsystem omits all
--** use of malloc(). The SQLite user supplies a block of memory
--** before calling sqlite3_initialize() from which allocations
--** are made and returned by the xMalloc() and xRealloc() 
--** implementations. Once sqlite3_initialize() has been called,
--** the amount of memory available to SQLite is fixed and cannot
--** be changed.
-+** 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.
- **
--** This version of the memory allocation subsystem is included
--** in the build only if SQLITE_ENABLE_MEMSYS3 is defined.
-+** 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 implemention 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
- 
--/*
--** This version of the memory allocator is only built into the library
--** SQLITE_ENABLE_MEMSYS3 is defined. Defining this symbol does not
--** mean that the library will use a memory-pool by default, just that
--** it is available. The mempool allocator is activated by calling
--** sqlite3_config().
--*/
--#ifdef SQLITE_ENABLE_MEMSYS3
- 
- /*
--** Maximum size (in Mem3Blocks) of a "small" chunk.
-+** A structure for holding a single date and time.
- */
--#define MX_SMALL 10
-+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 */
-+};
- 
- 
- /*
--** Number of freelist hash slots
-+** 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.
- */
--#define N_HASH  61
-+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;
-+}
- 
- /*
--** A memory allocation (also called a "chunk") consists of two or 
--** more blocks where each block is 8 bytes.  The first 8 bytes are 
--** a header that is not returned to the user.
-+** Parse a timezone extension on the end of a date-time.
-+** The extension is of the form:
- **
--** A chunk is two or more blocks that is either checked out or
--** free.  The first block has format u.hdr.  u.hdr.size4x is 4 times the
--** size of the allocation in blocks if the allocation is free.
--** The u.hdr.size4x&1 bit is true if the chunk is checked out and
--** false if the chunk is on the freelist.  The u.hdr.size4x&2 bit
--** is true if the previous chunk is checked out and false if the
--** previous chunk is free.  The u.hdr.prevSize field is the size of
--** the previous chunk in blocks if the previous chunk is on the
--** freelist. If the previous chunk is checked out, then
--** u.hdr.prevSize can be part of the data for that chunk and should
--** not be read or written.
-+**        (+/-)HH:MM
- **
--** We often identify a chunk by its index in mem3.aPool[].  When
--** this is done, the chunk index refers to the second block of
--** the chunk.  In this way, the first chunk has an index of 1.
--** A chunk index of 0 means "no such chunk" and is the equivalent
--** of a NULL pointer.
-+** Or the "zulu" notation:
- **
--** The second block of free chunks is of the form u.list.  The
--** two fields form a double-linked list of chunks of related sizes.
--** Pointers to the head of the list are stored in mem3.aiSmall[] 
--** for smaller chunks and mem3.aiHash[] for larger chunks.
-+**        Z
- **
--** The second block of a chunk is user data if the chunk is checked 
--** out.  If a chunk is checked out, the user data may extend into
--** the u.hdr.prevSize value of the following chunk.
--*/
--typedef struct Mem3Block Mem3Block;
--struct Mem3Block {
--  union {
--    struct {
--      u32 prevSize;   /* Size of previous chunk in Mem3Block elements */
--      u32 size4x;     /* 4x the size of current chunk in Mem3Block elements */
--    } hdr;
--    struct {
--      u32 next;       /* Index in mem3.aPool[] of next free chunk */
--      u32 prev;       /* Index in mem3.aPool[] of previous free chunk */
--    } list;
--  } u;
--};
--
--/*
--** All of the static variables used by this module are collected
--** into a single structure named "mem3".  This is to keep the
--** static variables organized and to reduce namespace pollution
--** when this module is combined with other in the amalgamation.
--*/
--static SQLITE_WSD struct Mem3Global {
--  /*
--  ** Memory available for allocation. nPool is the size of the array
--  ** (in Mem3Blocks) pointed to by aPool less 2.
--  */
--  u32 nPool;
--  Mem3Block *aPool;
--
--  /*
--  ** True if we are evaluating an out-of-memory callback.
--  */
--  int alarmBusy;
--  
--  /*
--  ** Mutex to control access to the memory allocation subsystem.
--  */
--  sqlite3_mutex *mutex;
--  
--  /*
--  ** The minimum amount of free space that we have seen.
--  */
--  u32 mnMaster;
--
--  /*
--  ** iMaster is the index of the master chunk.  Most new allocations
--  ** occur off of this chunk.  szMaster is the size (in Mem3Blocks)
--  ** of the current master.  iMaster is 0 if there is not master chunk.
--  ** The master chunk is not in either the aiHash[] or aiSmall[].
--  */
--  u32 iMaster;
--  u32 szMaster;
--
--  /*
--  ** Array of lists of free blocks according to the block size 
--  ** for smaller chunks, or a hash on the block size for larger
--  ** chunks.
--  */
--  u32 aiSmall[MX_SMALL-1];   /* For sizes 2 through MX_SMALL, inclusive */
--  u32 aiHash[N_HASH];        /* For sizes MX_SMALL+1 and larger */
--} mem3 = { 97535575 };
--
--#define mem3 GLOBAL(struct Mem3Global, mem3)
--
--/*
--** Unlink the chunk at mem3.aPool[i] from list it is currently
--** on.  *pRoot is the list that i is a member of.
-+** 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 void memsys3UnlinkFromList(u32 i, u32 *pRoot){
--  u32 next = mem3.aPool[i].u.list.next;
--  u32 prev = mem3.aPool[i].u.list.prev;
--  assert( sqlite3_mutex_held(mem3.mutex) );
--  if( prev==0 ){
--    *pRoot = next;
-+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{
--    mem3.aPool[prev].u.list.next = next;
-+    return c!=0;
-   }
--  if( next ){
--    mem3.aPool[next].u.list.prev = prev;
-+  zDate++;
-+  if( getDigits(zDate, 2, 0, 14, ':', &nHr, 2, 0, 59, 0, &nMn)!=2 ){
-+    return 1;
-   }
--  mem3.aPool[i].u.list.next = 0;
--  mem3.aPool[i].u.list.prev = 0;
-+  zDate += 5;
-+  p->tz = sgn*(nMn + nHr*60);
-+zulu_time:
-+  while( sqlite3Isspace(*zDate) ){ zDate++; }
-+  return *zDate!=0;
- }
- 
- /*
--** Unlink the chunk at index i from 
--** whatever list is currently a member of.
-+** 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 void memsys3Unlink(u32 i){
--  u32 size, hash;
--  assert( sqlite3_mutex_held(mem3.mutex) );
--  assert( (mem3.aPool[i-1].u.hdr.size4x & 1)==0 );
--  assert( i>=1 );
--  size = mem3.aPool[i-1].u.hdr.size4x/4;
--  assert( size==mem3.aPool[i+size-1].u.hdr.prevSize );
--  assert( size>=2 );
--  if( size <= MX_SMALL ){
--    memsys3UnlinkFromList(i, &mem3.aiSmall[size-2]);
-+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{
--    hash = size % N_HASH;
--    memsys3UnlinkFromList(i, &mem3.aiHash[hash]);
-+    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;
- }
- 
- /*
--** Link the chunk at mem3.aPool[i] so that is on the list rooted
--** at *pRoot.
-+** 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 memsys3LinkIntoList(u32 i, u32 *pRoot){
--  assert( sqlite3_mutex_held(mem3.mutex) );
--  mem3.aPool[i].u.list.next = *pRoot;
--  mem3.aPool[i].u.list.prev = 0;
--  if( *pRoot ){
--    mem3.aPool[*pRoot].u.list.prev = i;
-+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;
-+    }
-   }
--  *pRoot = i;
- }
- 
- /*
--** Link the chunk at index i into either the appropriate
--** small chunk list, or into the large chunk hash table.
-+** 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 void memsys3Link(u32 i){
--  u32 size, hash;
--  assert( sqlite3_mutex_held(mem3.mutex) );
--  assert( i>=1 );
--  assert( (mem3.aPool[i-1].u.hdr.size4x & 1)==0 );
--  size = mem3.aPool[i-1].u.hdr.size4x/4;
--  assert( size==mem3.aPool[i+size-1].u.hdr.prevSize );
--  assert( size>=2 );
--  if( size <= MX_SMALL ){
--    memsys3LinkIntoList(i, &mem3.aiSmall[size-2]);
-+static int parseYyyyMmDd(const char *zDate, DateTime *p){
-+  int Y, M, D, neg;
-+
-+  if( zDate[0]=='-' ){
-+    zDate++;
-+    neg = 1;
-   }else{
--    hash = size % N_HASH;
--    memsys3LinkIntoList(i, &mem3.aiHash[hash]);
-+    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;
- }
- 
- /*
--** If the STATIC_MEM mutex is not already held, obtain it now. The mutex
--** will already be held (obtained by code in malloc.c) if
--** sqlite3GlobalConfig.bMemStat is true.
-+** Set the time to the current time reported by the VFS.
-+**
-+** Return the number of errors.
- */
--static void memsys3Enter(void){
--  if( sqlite3GlobalConfig.bMemstat==0 && mem3.mutex==0 ){
--    mem3.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
-+static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
-+  sqlite3 *db = sqlite3_context_db_handle(context);
-+  if( sqlite3OsCurrentTimeInt64(db->pVfs, &p->iJD)==SQLITE_OK ){
-+    p->validJD = 1;
-+    return 0;
-+  }else{
-+    return 1;
-   }
--  sqlite3_mutex_enter(mem3.mutex);
--}
--static void memsys3Leave(void){
--  sqlite3_mutex_leave(mem3.mutex);
- }
- 
- /*
--** Called when we are unable to satisfy an allocation of nBytes.
--*/
--static void memsys3OutOfMemory(int nByte){
--  if( !mem3.alarmBusy ){
--    mem3.alarmBusy = 1;
--    assert( sqlite3_mutex_held(mem3.mutex) );
--    sqlite3_mutex_leave(mem3.mutex);
--    sqlite3_release_memory(nByte);
--    sqlite3_mutex_enter(mem3.mutex);
--    mem3.alarmBusy = 0;
--  }
--}
--
--
--/*
--** Chunk i is a free chunk that has been unlinked.  Adjust its 
--** size parameters for check-out and return a pointer to the 
--** user portion of the chunk.
--*/
--static void *memsys3Checkout(u32 i, u32 nBlock){
--  u32 x;
--  assert( sqlite3_mutex_held(mem3.mutex) );
--  assert( i>=1 );
--  assert( mem3.aPool[i-1].u.hdr.size4x/4==nBlock );
--  assert( mem3.aPool[i+nBlock-1].u.hdr.prevSize==nBlock );
--  x = mem3.aPool[i-1].u.hdr.size4x;
--  mem3.aPool[i-1].u.hdr.size4x = nBlock*4 | 1 | (x&2);
--  mem3.aPool[i+nBlock-1].u.hdr.prevSize = nBlock;
--  mem3.aPool[i+nBlock-1].u.hdr.size4x |= 2;
--  return &mem3.aPool[i];
--}
--
--/*
--** Carve a piece off of the end of the mem3.iMaster free chunk.
--** Return a pointer to the new allocation.  Or, if the master chunk
--** is not large enough, return 0.
--*/
--static void *memsys3FromMaster(u32 nBlock){
--  assert( sqlite3_mutex_held(mem3.mutex) );
--  assert( mem3.szMaster>=nBlock );
--  if( nBlock>=mem3.szMaster-1 ){
--    /* Use the entire master */
--    void *p = memsys3Checkout(mem3.iMaster, mem3.szMaster);
--    mem3.iMaster = 0;
--    mem3.szMaster = 0;
--    mem3.mnMaster = 0;
--    return p;
--  }else{
--    /* Split the master block.  Return the tail. */
--    u32 newi, x;
--    newi = mem3.iMaster + mem3.szMaster - nBlock;
--    assert( newi > mem3.iMaster+1 );
--    mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = nBlock;
--    mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x |= 2;
--    mem3.aPool[newi-1].u.hdr.size4x = nBlock*4 + 1;
--    mem3.szMaster -= nBlock;
--    mem3.aPool[newi-1].u.hdr.prevSize = mem3.szMaster;
--    x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2;
--    mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x;
--    if( mem3.szMaster < mem3.mnMaster ){
--      mem3.mnMaster = mem3.szMaster;
--    }
--    return (void*)&mem3.aPool[newi];
--  }
--}
--
--/*
--** *pRoot is the head of a list of free chunks of the same size
--** or same size hash.  In other words, *pRoot is an entry in either
--** mem3.aiSmall[] or mem3.aiHash[].  
-+** Attempt to parse the given string into a Julian Day Number.  Return
-+** the number of errors.
- **
--** This routine examines all entries on the given list and tries
--** to coalesce each entries with adjacent free chunks.  
-+** The following are acceptable forms for the input string:
- **
--** If it sees a chunk that is larger than mem3.iMaster, it replaces 
--** the current mem3.iMaster with the new larger chunk.  In order for
--** this mem3.iMaster replacement to work, the master chunk must be
--** linked into the hash tables.  That is not the normal state of
--** affairs, of course.  The calling routine must link the master
--** chunk before invoking this routine, then must unlink the (possibly
--** changed) master chunk once this routine has finished.
-+**      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 void memsys3Merge(u32 *pRoot){
--  u32 iNext, prev, size, i, x;
--
--  assert( sqlite3_mutex_held(mem3.mutex) );
--  for(i=*pRoot; i>0; i=iNext){
--    iNext = mem3.aPool[i].u.list.next;
--    size = mem3.aPool[i-1].u.hdr.size4x;
--    assert( (size&1)==0 );
--    if( (size&2)==0 ){
--      memsys3UnlinkFromList(i, pRoot);
--      assert( i > mem3.aPool[i-1].u.hdr.prevSize );
--      prev = i - mem3.aPool[i-1].u.hdr.prevSize;
--      if( prev==iNext ){
--        iNext = mem3.aPool[prev].u.list.next;
--      }
--      memsys3Unlink(prev);
--      size = i + size/4 - prev;
--      x = mem3.aPool[prev-1].u.hdr.size4x & 2;
--      mem3.aPool[prev-1].u.hdr.size4x = size*4 | x;
--      mem3.aPool[prev+size-1].u.hdr.prevSize = size;
--      memsys3Link(prev);
--      i = prev;
--    }else{
--      size /= 4;
--    }
--    if( size>mem3.szMaster ){
--      mem3.iMaster = i;
--      mem3.szMaster = size;
--    }
-+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;
- }
- 
- /*
--** Return a block of memory of at least nBytes in size.
--** Return NULL if unable.
--**
--** This function assumes that the necessary mutexes, if any, are
--** already held by the caller. Hence "Unsafe".
-+** Compute the Year, Month, and Day from the julian day number.
- */
--static void *memsys3MallocUnsafe(int nByte){
--  u32 i;
--  u32 nBlock;
--  u32 toFree;
--
--  assert( sqlite3_mutex_held(mem3.mutex) );
--  assert( sizeof(Mem3Block)==8 );
--  if( nByte<=12 ){
--    nBlock = 2;
--  }else{
--    nBlock = (nByte + 11)/8;
--  }
--  assert( nBlock>=2 );
--
--  /* STEP 1:
--  ** Look for an entry of the correct size in either the small
--  ** chunk table or in the large chunk hash table.  This is
--  ** successful most of the time (about 9 times out of 10).
--  */
--  if( nBlock <= MX_SMALL ){
--    i = mem3.aiSmall[nBlock-2];
--    if( i>0 ){
--      memsys3UnlinkFromList(i, &mem3.aiSmall[nBlock-2]);
--      return memsys3Checkout(i, nBlock);
--    }
-+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{
--    int hash = nBlock % N_HASH;
--    for(i=mem3.aiHash[hash]; i>0; i=mem3.aPool[i].u.list.next){
--      if( mem3.aPool[i-1].u.hdr.size4x/4==nBlock ){
--        memsys3UnlinkFromList(i, &mem3.aiHash[hash]);
--        return memsys3Checkout(i, nBlock);
--      }
--    }
--  }
--
--  /* STEP 2:
--  ** Try to satisfy the allocation by carving a piece off of the end
--  ** of the master chunk.  This step usually works if step 1 fails.
--  */
--  if( mem3.szMaster>=nBlock ){
--    return memsys3FromMaster(nBlock);
--  }
--
--
--  /* STEP 3:  
--  ** Loop through the entire memory pool.  Coalesce adjacent free
--  ** chunks.  Recompute the master chunk as the largest free chunk.
--  ** Then try again to satisfy the allocation by carving a piece off
--  ** of the end of the master chunk.  This step happens very
--  ** rarely (we hope!)
--  */
--  for(toFree=nBlock*16; toFree<(mem3.nPool*16); toFree *= 2){
--    memsys3OutOfMemory(toFree);
--    if( mem3.iMaster ){
--      memsys3Link(mem3.iMaster);
--      mem3.iMaster = 0;
--      mem3.szMaster = 0;
--    }
--    for(i=0; i<N_HASH; i++){
--      memsys3Merge(&mem3.aiHash[i]);
--    }
--    for(i=0; i<MX_SMALL-1; i++){
--      memsys3Merge(&mem3.aiSmall[i]);
--    }
--    if( mem3.szMaster ){
--      memsys3Unlink(mem3.iMaster);
--      if( mem3.szMaster>=nBlock ){
--        return memsys3FromMaster(nBlock);
--      }
--    }
-+    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;
-   }
--
--  /* If none of the above worked, then we fail. */
--  return 0;
-+  p->validYMD = 1;
- }
- 
- /*
--** Free an outstanding memory allocation.
--**
--** This function assumes that the necessary mutexes, if any, are
--** already held by the caller. Hence "Unsafe".
-+** Compute the Hour, Minute, and Seconds from the julian day number.
- */
--static void memsys3FreeUnsafe(void *pOld){
--  Mem3Block *p = (Mem3Block*)pOld;
--  int i;
--  u32 size, x;
--  assert( sqlite3_mutex_held(mem3.mutex) );
--  assert( p>mem3.aPool && p<&mem3.aPool[mem3.nPool] );
--  i = p - mem3.aPool;
--  assert( (mem3.aPool[i-1].u.hdr.size4x&1)==1 );
--  size = mem3.aPool[i-1].u.hdr.size4x/4;
--  assert( i+size<=mem3.nPool+1 );
--  mem3.aPool[i-1].u.hdr.size4x &= ~1;
--  mem3.aPool[i+size-1].u.hdr.prevSize = size;
--  mem3.aPool[i+size-1].u.hdr.size4x &= ~2;
--  memsys3Link(i);
--
--  /* Try to expand the master using the newly freed chunk */
--  if( mem3.iMaster ){
--    while( (mem3.aPool[mem3.iMaster-1].u.hdr.size4x&2)==0 ){
--      size = mem3.aPool[mem3.iMaster-1].u.hdr.prevSize;
--      mem3.iMaster -= size;
--      mem3.szMaster += size;
--      memsys3Unlink(mem3.iMaster);
--      x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2;
--      mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x;
--      mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = mem3.szMaster;
--    }
--    x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2;
--    while( (mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x&1)==0 ){
--      memsys3Unlink(mem3.iMaster+mem3.szMaster);
--      mem3.szMaster += mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x/4;
--      mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x;
--      mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = mem3.szMaster;
--    }
--  }
-+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;
- }
- 
- /*
--** Return the size of an outstanding allocation, in bytes.  The
--** size returned omits the 8-byte header overhead.  This only
--** works for chunks that are currently checked out.
-+** Compute both YMD and HMS
- */
--static int memsys3Size(void *p){
--  Mem3Block *pBlock;
--  if( p==0 ) return 0;
--  pBlock = (Mem3Block*)p;
--  assert( (pBlock[-1].u.hdr.size4x&1)!=0 );
--  return (pBlock[-1].u.hdr.size4x&~3)*2 - 4;
-+static void computeYMD_HMS(DateTime *p){
-+  computeYMD(p);
-+  computeHMS(p);
- }
- 
- /*
--** Round up a request size to the next valid allocation size.
-+** Clear the YMD and HMS and the TZ
- */
--static int memsys3Roundup(int n){
--  if( n<=12 ){
--    return 12;
--  }else{
--    return ((n+11)&~7) - 4;
--  }
-+static void clearYMD_HMS_TZ(DateTime *p){
-+  p->validYMD = 0;
-+  p->validHMS = 0;
-+  p->validTZ = 0;
- }
- 
- /*
--** Allocate nBytes of memory.
-+** 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().
- */
--static void *memsys3Malloc(int nBytes){
--  sqlite3_int64 *p;
--  assert( nBytes>0 );          /* malloc.c filters out 0 byte requests */
--  memsys3Enter();
--  p = memsys3MallocUnsafe(nBytes);
--  memsys3Leave();
--  return (void*)p; 
--}
-+#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) && \
-+     defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE)
-+#define HAVE_LOCALTIME_S 1
-+#endif
- 
-+#ifndef SQLITE_OMIT_LOCALTIME
- /*
--** Free memory.
-+** 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.
- */
--static void memsys3Free(void *pPrior){
--  assert( pPrior );
--  memsys3Enter();
--  memsys3FreeUnsafe(pPrior);
--  memsys3Leave();
-+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)
-+  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 defined(HAVE_LOCALTIME_R) && 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
- /*
--** Change the size of an existing memory allocation
-+** 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 void *memsys3Realloc(void *pPrior, int nBytes){
--  int nOld;
--  void *p;
--  if( pPrior==0 ){
--    return sqlite3_malloc(nBytes);
-+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 ){
-+    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;
-   }
--  if( nBytes<=0 ){
--    sqlite3_free(pPrior);
-+  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;
-   }
--  nOld = memsys3Size(pPrior);
--  if( nBytes<=nOld && nBytes>=nOld-128 ){
--    return pPrior;
--  }
--  memsys3Enter();
--  p = memsys3MallocUnsafe(nBytes);
--  if( p ){
--    if( nOld<nBytes ){
--      memcpy(p, pPrior, nOld);
--    }else{
--      memcpy(p, pPrior, nBytes);
--    }
--    memsys3FreeUnsafe(pPrior);
--  }
--  memsys3Leave();
--  return p;
-+  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 */
- 
- /*
--** Initialize this module.
-+** 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 memsys3Init(void *NotUsed){
--  UNUSED_PARAMETER(NotUsed);
--  if( !sqlite3GlobalConfig.pHeap ){
--    return SQLITE_ERROR;
-+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]];
-   }
--
--  /* Store a pointer to the memory block in global structure mem3. */
--  assert( sizeof(Mem3Block)==8 );
--  mem3.aPool = (Mem3Block *)sqlite3GlobalConfig.pHeap;
--  mem3.nPool = (sqlite3GlobalConfig.nHeap / sizeof(Mem3Block)) - 2;
--
--  /* Initialize the master block. */
--  mem3.szMaster = mem3.nPool;
--  mem3.mnMaster = mem3.szMaster;
--  mem3.iMaster = 1;
--  mem3.aPool[0].u.hdr.size4x = (mem3.szMaster<<2) + 2;
--  mem3.aPool[mem3.nPool].u.hdr.prevSize = mem3.nPool;
--  mem3.aPool[mem3.nPool].u.hdr.size4x = 1;
--
--  return SQLITE_OK;
--}
--
--/*
--** Deinitialize this module.
--*/
--static void memsys3Shutdown(void *NotUsed){
--  UNUSED_PARAMETER(NotUsed);
--  mem3.mutex = 0;
--  return;
--}
--
--
--
--/*
--** Open the file indicated and write a log of all unfreed memory 
--** allocations into that log.
--*/
--SQLITE_PRIVATE void sqlite3Memsys3Dump(const char *zFilename){
--#ifdef SQLITE_DEBUG
--  FILE *out;
--  u32 i, j;
--  u32 size;
--  if( zFilename==0 || zFilename[0]==0 ){
--    out = stdout;
--  }else{
--    out = fopen(zFilename, "w");
--    if( out==0 ){
--      fprintf(stderr, "** Unable to output memory debug output log: %s **\n",
--                      zFilename);
--      return;
--    }
--  }
--  memsys3Enter();
--  fprintf(out, "CHUNKS:\n");
--  for(i=1; i<=mem3.nPool; i+=size/4){
--    size = mem3.aPool[i-1].u.hdr.size4x;
--    if( size/4<=1 ){
--      fprintf(out, "%p size error\n", &mem3.aPool[i]);
--      assert( 0 );
-+  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;
-     }
--    if( (size&1)==0 && mem3.aPool[i+size/4-1].u.hdr.prevSize!=size/4 ){
--      fprintf(out, "%p tail size does not match\n", &mem3.aPool[i]);
--      assert( 0 );
-+#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;
-     }
--    if( ((mem3.aPool[i+size/4-1].u.hdr.size4x&2)>>1)!=(size&1) ){
--      fprintf(out, "%p tail checkout bit is incorrect\n", &mem3.aPool[i]);
--      assert( 0 );
-+    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;
-     }
--    if( size&1 ){
--      fprintf(out, "%p %6d bytes checked out\n", &mem3.aPool[i], (size/4)*8-8);
--    }else{
--      fprintf(out, "%p %6d bytes free%s\n", &mem3.aPool[i], (size/4)*8-8,
--                  i==mem3.iMaster ? " **master**" : "");
-+    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;
-     }
--  }
--  for(i=0; i<MX_SMALL-1; i++){
--    if( mem3.aiSmall[i]==0 ) continue;
--    fprintf(out, "small(%2d):", i);
--    for(j = mem3.aiSmall[i]; j>0; j=mem3.aPool[j].u.list.next){
--      fprintf(out, " %p(%d)", &mem3.aPool[j],
--              (mem3.aPool[j-1].u.hdr.size4x/4)*8-8);
-+    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;
-     }
--    fprintf(out, "\n"); 
--  }
--  for(i=0; i<N_HASH; i++){
--    if( mem3.aiHash[i]==0 ) continue;
--    fprintf(out, "hash(%2d):", i);
--    for(j = mem3.aiHash[i]; j>0; j=mem3.aPool[j].u.list.next){
--      fprintf(out, " %p(%d)", &mem3.aPool[j],
--              (mem3.aPool[j-1].u.hdr.size4x/4)*8-8);
-+    default: {
-+      break;
-     }
--    fprintf(out, "\n"); 
--  }
--  fprintf(out, "master=%d\n", mem3.iMaster);
--  fprintf(out, "nowUsed=%d\n", mem3.nPool*8 - mem3.szMaster*8);
--  fprintf(out, "mxUsed=%d\n", mem3.nPool*8 - mem3.mnMaster*8);
--  sqlite3_mutex_leave(mem3.mutex);
--  if( out==stdout ){
--    fflush(stdout);
--  }else{
--    fclose(out);
-   }
--#else
--  UNUSED_PARAMETER(zFilename);
--#endif
-+  return rc;
- }
- 
- /*
--** This routine is the only routine in this file with external 
--** linkage.
--**
--** 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.
-+** 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.
- **
--** This routine is only called by sqlite3_config(), and therefore
--** is not required to be threadsafe (it is not).
-+** If there are zero parameters (if even argv[0] is undefined)
-+** then assume a default value of "now" for argv[0].
- */
--SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void){
--  static const sqlite3_mem_methods mempoolMethods = {
--     memsys3Malloc,
--     memsys3Free,
--     memsys3Realloc,
--     memsys3Size,
--     memsys3Roundup,
--     memsys3Init,
--     memsys3Shutdown,
--     0
--  };
--  return &mempoolMethods;
-+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;
- }
- 
--#endif /* SQLITE_ENABLE_MEMSYS3 */
--
--/************** End of mem3.c ************************************************/
--/************** Begin file mem5.c ********************************************/
--/*
--** 2007 October 14
--**
--** 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 a memory
--** allocation subsystem for use by SQLite. 
--**
--** This version of the memory allocation subsystem omits all
--** use of malloc(). The application gives SQLite a block of memory
--** before calling sqlite3_initialize() from which allocations
--** are made and returned by the xMalloc() and xRealloc() 
--** implementations. Once sqlite3_initialize() has been called,
--** the amount of memory available to SQLite is fixed and cannot
--** be changed.
--**
--** This version of the memory allocation subsystem is included
--** in the build only if SQLITE_ENABLE_MEMSYS5 is defined.
--**
--** This memory allocator uses the following algorithm:
--**
--**   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.
--**
--**   3.  New memory is allocated from the first available free block.
--**
--** This algorithm is described in: J. M. Robson. "Bounds for Some Functions
--** Concerning Dynamic Storage Allocation". Journal of the Association for
--** Computing Machinery, Volume 21, Number 8, July 1974, pages 491-499.
--** 
--** Let n be the size of the largest allocation divided by the minimum
--** allocation size (after rounding all sizes up to a power of 2.)  Let M
--** be the maximum amount of memory ever outstanding at one time.  Let
--** N be the total amount of memory available for allocation.  Robson
--** proved that this memory allocator will never breakdown due to 
--** fragmentation as long as the following constraint holds:
--**
--**      N >=  M*(1 + log2(n)/2) - n + 1
--**
--** The sqlite3_status() logic tracks the maximum values of n and M so
--** that an application can, at any time, verify this constraint.
--*/
- 
- /*
--** This version of the memory allocator is used only when 
--** SQLITE_ENABLE_MEMSYS5 is defined.
-+** The following routines implement the various date and time functions
-+** of SQLite.
- */
--#ifdef SQLITE_ENABLE_MEMSYS5
- 
- /*
--** A minimum allocation is an instance of the following structure.
--** Larger allocations are an array of these structures where the
--** size of the array is a power of 2.
-+**    julianday( TIMESTRING, MOD, MOD, ...)
- **
--** The size of this object must be a power of two.  That fact is
--** verified in memsys5Init().
--*/
--typedef struct Mem5Link Mem5Link;
--struct Mem5Link {
--  int next;       /* Index of next free chunk */
--  int prev;       /* Index of previous free chunk */
--};
--
--/*
--** Maximum size of any allocation is ((1<<LOGMAX)*mem5.szAtom). Since
--** mem5.szAtom is always at least 8 and 32-bit integers are used,
--** it is not actually possible to reach this limit.
--*/
--#define LOGMAX 30
--
--/*
--** Masks used for mem5.aCtrl[] elements.
--*/
--#define CTRL_LOGSIZE  0x1f    /* Log2 Size of this block */
--#define CTRL_FREE     0x20    /* True if not checked out */
--
--/*
--** All of the static variables used by this module are collected
--** into a single structure named "mem5".  This is to keep the
--** static variables organized and to reduce namespace pollution
--** when this module is combined with other in the amalgamation.
--*/
--static SQLITE_WSD struct Mem5Global {
--  /*
--  ** Memory available for allocation
--  */
--  int szAtom;      /* Smallest possible allocation in bytes */
--  int nBlock;      /* Number of szAtom sized blocks in zPool */
--  u8 *zPool;       /* Memory available to be allocated */
--  
--  /*
--  ** Mutex to control access to the memory allocation subsystem.
--  */
--  sqlite3_mutex *mutex;
--
--  /*
--  ** Performance statistics
--  */
--  u64 nAlloc;         /* Total number of calls to malloc */
--  u64 totalAlloc;     /* Total of all malloc calls - includes internal frag */
--  u64 totalExcess;    /* Total internal fragmentation */
--  u32 currentOut;     /* Current checkout, including internal fragmentation */
--  u32 currentCount;   /* Current number of distinct checkouts */
--  u32 maxOut;         /* Maximum instantaneous currentOut */
--  u32 maxCount;       /* Maximum instantaneous currentCount */
--  u32 maxRequest;     /* Largest allocation (exclusive of internal frag) */
--  
--  /*
--  ** Lists of free blocks.  aiFreelist[0] is a list of free blocks of
--  ** size mem5.szAtom.  aiFreelist[1] holds blocks of size szAtom*2.
--  ** and so forth.
--  */
--  int aiFreelist[LOGMAX+1];
--
--  /*
--  ** Space for tracking which blocks are checked out and the size
--  ** of each block.  One byte per block.
--  */
--  u8 *aCtrl;
--
--} mem5;
--
--/*
--** Access the static variable through a macro for SQLITE_OMIT_WSD
--*/
--#define mem5 GLOBAL(struct Mem5Global, mem5)
--
--/*
--** Assuming mem5.zPool is divided up into an array of Mem5Link
--** structures, return a pointer to the idx-th such lik.
-+** Return the julian day number of the date specified in the arguments
- */
--#define MEM5LINK(idx) ((Mem5Link *)(&mem5.zPool[(idx)*mem5.szAtom]))
-+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);
-+  }
-+}
- 
- /*
--** Unlink the chunk at mem5.aPool[i] from list it is currently
--** on.  It should be found on mem5.aiFreelist[iLogsize].
-+**    datetime( TIMESTRING, MOD, MOD, ...)
-+**
-+** Return YYYY-MM-DD HH:MM:SS
- */
--static void memsys5Unlink(int i, int iLogsize){
--  int next, prev;
--  assert( i>=0 && i<mem5.nBlock );
--  assert( iLogsize>=0 && iLogsize<=LOGMAX );
--  assert( (mem5.aCtrl[i] & CTRL_LOGSIZE)==iLogsize );
--
--  next = MEM5LINK(i)->next;
--  prev = MEM5LINK(i)->prev;
--  if( prev<0 ){
--    mem5.aiFreelist[iLogsize] = next;
--  }else{
--    MEM5LINK(prev)->next = next;
--  }
--  if( next>=0 ){
--    MEM5LINK(next)->prev = prev;
-+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);
-   }
- }
- 
- /*
--** Link the chunk at mem5.aPool[i] so that is on the iLogsize
--** free list.
-+**    time( TIMESTRING, MOD, MOD, ...)
-+**
-+** Return HH:MM:SS
- */
--static void memsys5Link(int i, int iLogsize){
--  int x;
--  assert( sqlite3_mutex_held(mem5.mutex) );
--  assert( i>=0 && i<mem5.nBlock );
--  assert( iLogsize>=0 && iLogsize<=LOGMAX );
--  assert( (mem5.aCtrl[i] & CTRL_LOGSIZE)==iLogsize );
--
--  x = MEM5LINK(i)->next = mem5.aiFreelist[iLogsize];
--  MEM5LINK(i)->prev = -1;
--  if( x>=0 ){
--    assert( x<mem5.nBlock );
--    MEM5LINK(x)->prev = i;
-+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);
-   }
--  mem5.aiFreelist[iLogsize] = i;
- }
- 
- /*
--** If the STATIC_MEM mutex is not already held, obtain it now. The mutex
--** will already be held (obtained by code in malloc.c) if
--** sqlite3GlobalConfig.bMemStat is true.
-+**    date( TIMESTRING, MOD, MOD, ...)
-+**
-+** Return YYYY-MM-DD
- */
--static void memsys5Enter(void){
--  sqlite3_mutex_enter(mem5.mutex);
--}
--static void memsys5Leave(void){
--  sqlite3_mutex_leave(mem5.mutex);
--}
--
--/*
--** Return the size of an outstanding allocation, in bytes.  The
--** size returned omits the 8-byte header overhead.  This only
--** works for chunks that are currently checked out.
--*/
--static int memsys5Size(void *p){
--  int iSize = 0;
--  if( p ){
--    int i = ((u8 *)p-mem5.zPool)/mem5.szAtom;
--    assert( i>=0 && i<mem5.nBlock );
--    iSize = mem5.szAtom * (1 << (mem5.aCtrl[i]&CTRL_LOGSIZE));
--  }
--  return iSize;
--}
--
--/*
--** Find the first entry on the freelist iLogsize.  Unlink that
--** entry and return its index. 
--*/
--static int memsys5UnlinkFirst(int iLogsize){
--  int i;
--  int iFirst;
--
--  assert( iLogsize>=0 && iLogsize<=LOGMAX );
--  i = iFirst = mem5.aiFreelist[iLogsize];
--  assert( iFirst>=0 );
--  while( i>0 ){
--    if( i<iFirst ) iFirst = i;
--    i = MEM5LINK(i)->next;
-+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);
-   }
--  memsys5Unlink(iFirst, iLogsize);
--  return iFirst;
- }
- 
- /*
--** Return a block of memory of at least nBytes in size.
--** Return NULL if unable.  Return NULL if nBytes==0.
-+**    strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
- **
--** The caller guarantees that nByte positive.
-+** Return a string described by FORMAT.  Conversions as follows:
- **
--** The caller has obtained a mutex prior to invoking this
--** routine so there is never any chance that two or more
--** threads can be in this routine at the same time.
-+**   %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 *memsys5MallocUnsafe(int nByte){
--  int i;           /* Index of a mem5.aPool[] slot */
--  int iBin;        /* Index into mem5.aiFreelist[] */
--  int iFullSz;     /* Size of allocation rounded up to power of 2 */
--  int iLogsize;    /* Log2 of iFullSz/POW2_MIN */
--
--  /* nByte must be a positive */
--  assert( nByte>0 );
--
--  /* Keep track of the maximum allocation request.  Even unfulfilled
--  ** requests are counted */
--  if( (u32)nByte>mem5.maxRequest ){
--    mem5.maxRequest = nByte;
--  }
--
--  /* Abort if the requested allocation size is larger than the largest
--  ** power of two that we can represent using 32-bit signed integers.
--  */
--  if( nByte > 0x40000000 ){
--    return 0;
-+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 = (const char*)sqlite3_value_text(argv[0]);
-+  char zBuf[100];
-+  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++;
-+    }
-   }
--
--  /* Round nByte up to the next valid power of two */
--  for(iFullSz=mem5.szAtom, iLogsize=0; iFullSz<nByte; iFullSz *= 2, iLogsize++){}
--
--  /* Make sure mem5.aiFreelist[iLogsize] contains at least one free
--  ** block.  If not, then split a block of the next larger power of
--  ** two in order to create a new free block of size iLogsize.
--  */
--  for(iBin=iLogsize; mem5.aiFreelist[iBin]<0 && iBin<=LOGMAX; iBin++){}
--  if( iBin>LOGMAX ){
--    testcase( sqlite3GlobalConfig.xLog!=0 );
--    sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes", nByte);
--    return 0;
-+  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;
-+    }
-   }
--  i = memsys5UnlinkFirst(iBin);
--  while( iBin>iLogsize ){
--    int newSize;
--
--    iBin--;
--    newSize = 1 << iBin;
--    mem5.aCtrl[i+newSize] = CTRL_FREE | iBin;
--    memsys5Link(i+newSize, iBin);
-+  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;
-+      }
-+    }
-   }
--  mem5.aCtrl[i] = iLogsize;
--
--  /* Update allocator performance statistics. */
--  mem5.nAlloc++;
--  mem5.totalAlloc += iFullSz;
--  mem5.totalExcess += iFullSz - nByte;
--  mem5.currentCount++;
--  mem5.currentOut += iFullSz;
--  if( mem5.maxCount<mem5.currentCount ) mem5.maxCount = mem5.currentCount;
--  if( mem5.maxOut<mem5.currentOut ) mem5.maxOut = mem5.currentOut;
--
--  /* Return a pointer to the allocated memory. */
--  return (void*)&mem5.zPool[i*mem5.szAtom];
-+  z[j] = 0;
-+  sqlite3_result_text(context, z, -1,
-+                      z==zBuf ? SQLITE_TRANSIENT : SQLITE_DYNAMIC);
- }
- 
- /*
--** Free an outstanding memory allocation.
-+** current_time()
-+**
-+** This function returns the same value as time('now').
- */
--static void memsys5FreeUnsafe(void *pOld){
--  u32 size, iLogsize;
--  int iBlock;
--
--  /* Set iBlock to the index of the block pointed to by pOld in 
--  ** the array of mem5.szAtom byte blocks pointed to by mem5.zPool.
--  */
--  iBlock = ((u8 *)pOld-mem5.zPool)/mem5.szAtom;
--
--  /* Check that the pointer pOld points to a valid, non-free block. */
--  assert( iBlock>=0 && iBlock<mem5.nBlock );
--  assert( ((u8 *)pOld-mem5.zPool)%mem5.szAtom==0 );
--  assert( (mem5.aCtrl[iBlock] & CTRL_FREE)==0 );
--
--  iLogsize = mem5.aCtrl[iBlock] & CTRL_LOGSIZE;
--  size = 1<<iLogsize;
--  assert( iBlock+size-1<(u32)mem5.nBlock );
--
--  mem5.aCtrl[iBlock] |= CTRL_FREE;
--  mem5.aCtrl[iBlock+size-1] |= CTRL_FREE;
--  assert( mem5.currentCount>0 );
--  assert( mem5.currentOut>=(size*mem5.szAtom) );
--  mem5.currentCount--;
--  mem5.currentOut -= size*mem5.szAtom;
--  assert( mem5.currentOut>0 || mem5.currentCount==0 );
--  assert( mem5.currentCount>0 || mem5.currentOut==0 );
--
--  mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize;
--  while( ALWAYS(iLogsize<LOGMAX) ){
--    int iBuddy;
--    if( (iBlock>>iLogsize) & 1 ){
--      iBuddy = iBlock - size;
--    }else{
--      iBuddy = iBlock + size;
--    }
--    assert( iBuddy>=0 );
--    if( (iBuddy+(1<<iLogsize))>mem5.nBlock ) break;
--    if( mem5.aCtrl[iBuddy]!=(CTRL_FREE | iLogsize) ) break;
--    memsys5Unlink(iBuddy, iLogsize);
--    iLogsize++;
--    if( iBuddy<iBlock ){
--      mem5.aCtrl[iBuddy] = CTRL_FREE | iLogsize;
--      mem5.aCtrl[iBlock] = 0;
--      iBlock = iBuddy;
--    }else{
--      mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize;
--      mem5.aCtrl[iBuddy] = 0;
--    }
--    size *= 2;
--  }
--  memsys5Link(iBlock, iLogsize);
-+static void ctimeFunc(
-+  sqlite3_context *context,
-+  int NotUsed,
-+  sqlite3_value **NotUsed2
-+){
-+  UNUSED_PARAMETER2(NotUsed, NotUsed2);
-+  timeFunc(context, 0, 0);
- }
- 
- /*
--** Allocate nBytes of memory
-+** current_date()
-+**
-+** This function returns the same value as date('now').
- */
--static void *memsys5Malloc(int nBytes){
--  sqlite3_int64 *p = 0;
--  if( nBytes>0 ){
--    memsys5Enter();
--    p = memsys5MallocUnsafe(nBytes);
--    memsys5Leave();
--  }
--  return (void*)p; 
-+static void cdateFunc(
-+  sqlite3_context *context,
-+  int NotUsed,
-+  sqlite3_value **NotUsed2
-+){
-+  UNUSED_PARAMETER2(NotUsed, NotUsed2);
-+  dateFunc(context, 0, 0);
- }
- 
- /*
--** Free memory.
-+** current_timestamp()
- **
--** The outer layer memory allocator prevents this routine from
--** being called with pPrior==0.
-+** This function returns the same value as datetime('now').
- */
--static void memsys5Free(void *pPrior){
--  assert( pPrior!=0 );
--  memsys5Enter();
--  memsys5FreeUnsafe(pPrior);
--  memsys5Leave();  
-+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
- /*
--** Change the size of an existing memory allocation.
--**
--** The outer layer memory allocator prevents this routine from
--** being called with pPrior==0.  
-+** 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.
- **
--** nBytes is always a value obtained from a prior call to
--** memsys5Round().  Hence nBytes is always a non-negative power
--** of two.  If nBytes==0 that means that an oversize allocation
--** (an allocation larger than 0x40000000) was requested and this
--** routine should return 0 without freeing pPrior.
-+** 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 *memsys5Realloc(void *pPrior, int nBytes){
--  int nOld;
--  void *p;
--  assert( pPrior!=0 );
--  assert( (nBytes&(nBytes-1))==0 );  /* EV: R-46199-30249 */
--  assert( nBytes>=0 );
--  if( nBytes==0 ){
--    return 0;
--  }
--  nOld = memsys5Size(pPrior);
--  if( nBytes<=nOld ){
--    return pPrior;
--  }
--  memsys5Enter();
--  p = memsys5MallocUnsafe(nBytes);
--  if( p ){
--    memcpy(p, pPrior, nOld);
--    memsys5FreeUnsafe(pPrior);
-+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);
-+
-+  db = sqlite3_context_db_handle(context);
-+  if( sqlite3OsCurrentTimeInt64(db->pVfs, &iT) ) return;
-+  t = iT/1000 - 10000*(sqlite3_int64)21086676;
-+#ifdef 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);
-   }
--  memsys5Leave();
--  return p;
- }
-+#endif
- 
- /*
--** Round up a request size to the next valid allocation size.  If
--** the allocation is too large to be handled by this allocation system,
--** return 0.
--**
--** All allocations must be a power of two and must be expressed by a
--** 32-bit signed integer.  Hence the largest allocation is 0x40000000
--** or 1073741824 bytes.
-+** This function registered all of the above C functions as SQL
-+** functions.  This should be the only routine in this file with
-+** external linkage.
- */
--static int memsys5Roundup(int n){
--  int iFullSz;
--  if( n > 0x40000000 ) return 0;
--  for(iFullSz=mem5.szAtom; iFullSz<n; iFullSz *= 2);
--  return iFullSz;
-+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 **********************************************/
- /*
--** Return the ceiling of the logarithm base 2 of iValue.
-+** 2005 November 29
- **
--** Examples:   memsys5Log(1) -> 0
--**             memsys5Log(2) -> 1
--**             memsys5Log(4) -> 2
--**             memsys5Log(5) -> 3
--**             memsys5Log(8) -> 3
--**             memsys5Log(9) -> 4
-+** 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.
- */
--static int memsys5Log(int iValue){
--  int iLog;
--  for(iLog=0; (iLog<(int)((sizeof(int)*8)-1)) && (1<<iLog)<iValue; iLog++);
--  return iLog;
--}
-+#define _SQLITE_OS_C_ 1
-+#undef _SQLITE_OS_C_
- 
- /*
--** Initialize the memory allocator.
-+** 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()
- **
--** This routine is not threadsafe.  The caller must be holding a mutex
--** to prevent multiple threads from entering at the same time.
- */
--static int memsys5Init(void *NotUsed){
--  int ii;            /* Loop counter */
--  int nByte;         /* Number of bytes of memory available to this allocator */
--  u8 *zByte;         /* Memory usable by this allocator */
--  int nMinLog;       /* Log base 2 of minimum allocation size in bytes */
--  int iOffset;       /* An offset into mem5.aCtrl[] */
--
--  UNUSED_PARAMETER(NotUsed);
--
--  /* For the purposes of this routine, disable the mutex */
--  mem5.mutex = 0;
-+#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 size of a Mem5Link object must be a power of two.  Verify that
--  ** this is case.
--  */
--  assert( (sizeof(Mem5Link)&(sizeof(Mem5Link)-1))==0 );
-+/*
-+** 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);
-+}
- 
--  nByte = sqlite3GlobalConfig.nHeap;
--  zByte = (u8*)sqlite3GlobalConfig.pHeap;
--  assert( zByte!=0 );  /* sqlite3_config() does not allow otherwise */
-+/*
-+** 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){
-+  DO_OS_MALLOC_TEST(id);
-+  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);
-+}
- 
--  /* boundaries on sqlite3GlobalConfig.mnReq are enforced in sqlite3_config() */
--  nMinLog = memsys5Log(sqlite3GlobalConfig.mnReq);
--  mem5.szAtom = (1<<nMinLog);
--  while( (int)sizeof(Mem5Link)>mem5.szAtom ){
--    mem5.szAtom = mem5.szAtom << 1;
--  }
-+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);
-+}
- 
--  mem5.nBlock = (nByte / (mem5.szAtom+sizeof(u8)));
--  mem5.zPool = zByte;
--  mem5.aCtrl = (u8 *)&mem5.zPool[mem5.nBlock*mem5.szAtom];
-+#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);
-+}
-+#else
-+/* No-op stubs to use when memory-mapped I/O is disabled */
-+SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){
-+  *pp = 0;
-+  return SQLITE_OK;
-+}
-+SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){
-+  return SQLITE_OK;
-+}
-+#endif
- 
--  for(ii=0; ii<=LOGMAX; ii++){
--    mem5.aiFreelist[ii] = -1;
-+/*
-+** The next group of routines are convenience wrappers around the
-+** VFS methods.
-+*/
-+SQLITE_PRIVATE int sqlite3OsOpen(
-+  sqlite3_vfs *pVfs, 
-+  const char *zPath, 
-+  sqlite3_file *pFile, 
-+  int flags, 
-+  int *pFlagsOut
-+){
-+  int rc;
-+  DO_OS_MALLOC_TEST(0);
-+  /* 0x87f7f is a mask of SQLITE_OPEN_ flags that are valid to be passed
-+  ** down into the VFS layer.  Some SQLITE_OPEN_ flags (for example,
-+  ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before
-+  ** reaching the VFS. */
-+  rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x87f7f, pFlagsOut);
-+  assert( rc==SQLITE_OK || pFile->pMethods==0 );
-+  return rc;
-+}
-+SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
-+  DO_OS_MALLOC_TEST(0);
-+  assert( dirSync==0 || dirSync==1 );
-+  return pVfs->xDelete(pVfs, zPath, dirSync);
-+}
-+SQLITE_PRIVATE int sqlite3OsAccess(
-+  sqlite3_vfs *pVfs, 
-+  const char *zPath, 
-+  int flags, 
-+  int *pResOut
-+){
-+  DO_OS_MALLOC_TEST(0);
-+  return pVfs->xAccess(pVfs, zPath, flags, pResOut);
-+}
-+SQLITE_PRIVATE int sqlite3OsFullPathname(
-+  sqlite3_vfs *pVfs, 
-+  const char *zPath, 
-+  int nPathOut, 
-+  char *zPathOut
-+){
-+  DO_OS_MALLOC_TEST(0);
-+  zPathOut[0] = 0;
-+  return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut);
-+}
-+#ifndef SQLITE_OMIT_LOAD_EXTENSION
-+SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
-+  return pVfs->xDlOpen(pVfs, zPath);
-+}
-+SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
-+  pVfs->xDlError(pVfs, nByte, zBufOut);
-+}
-+SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){
-+  return pVfs->xDlSym(pVfs, pHdle, zSym);
-+}
-+SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
-+  pVfs->xDlClose(pVfs, pHandle);
-+}
-+#endif /* SQLITE_OMIT_LOAD_EXTENSION */
-+SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
-+  return pVfs->xRandomness(pVfs, nByte, zBufOut);
-+}
-+SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
-+  return pVfs->xSleep(pVfs, nMicro);
-+}
-+SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
-+  int rc;
-+  /* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64()
-+  ** method to get the current date and time if that method is available
-+  ** (if iVersion is 2 or greater and the function pointer is not NULL) and
-+  ** will fall back to xCurrentTime() if xCurrentTimeInt64() is
-+  ** unavailable.
-+  */
-+  if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){
-+    rc = pVfs->xCurrentTimeInt64(pVfs, pTimeOut);
-+  }else{
-+    double r;
-+    rc = pVfs->xCurrentTime(pVfs, &r);
-+    *pTimeOut = (sqlite3_int64)(r*86400000.0);
-   }
-+  return rc;
-+}
- 
--  iOffset = 0;
--  for(ii=LOGMAX; ii>=0; ii--){
--    int nAlloc = (1<<ii);
--    if( (iOffset+nAlloc)<=mem5.nBlock ){
--      mem5.aCtrl[iOffset] = ii | CTRL_FREE;
--      memsys5Link(iOffset, ii);
--      iOffset += nAlloc;
-+SQLITE_PRIVATE int sqlite3OsOpenMalloc(
-+  sqlite3_vfs *pVfs, 
-+  const char *zFile, 
-+  sqlite3_file **ppFile, 
-+  int flags,
-+  int *pOutFlags
-+){
-+  int rc = SQLITE_NOMEM;
-+  sqlite3_file *pFile;
-+  pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile);
-+  if( pFile ){
-+    rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
-+    if( rc!=SQLITE_OK ){
-+      sqlite3_free(pFile);
-+    }else{
-+      *ppFile = pFile;
-     }
--    assert((iOffset+nAlloc)>mem5.nBlock);
--  }
--
--  /* If a mutex is required for normal operation, allocate one */
--  if( sqlite3GlobalConfig.bMemstat==0 ){
--    mem5.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
-   }
--
--  return SQLITE_OK;
-+  return rc;
-+}
-+SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *pFile){
-+  int rc = SQLITE_OK;
-+  assert( pFile );
-+  rc = sqlite3OsClose(pFile);
-+  sqlite3_free(pFile);
-+  return rc;
- }
- 
- /*
--** Deinitialize this module.
-+** This function is a wrapper around the OS specific implementation of
-+** sqlite3_os_init(). The purpose of the wrapper is to provide the
-+** ability to simulate a malloc failure, so that the handling of an
-+** error in sqlite3_os_init() by the upper layers can be tested.
- */
--static void memsys5Shutdown(void *NotUsed){
--  UNUSED_PARAMETER(NotUsed);
--  mem5.mutex = 0;
--  return;
-+SQLITE_PRIVATE int sqlite3OsInit(void){
-+  void *p = sqlite3_malloc(10);
-+  if( p==0 ) return SQLITE_NOMEM;
-+  sqlite3_free(p);
-+  return sqlite3_os_init();
- }
- 
--#ifdef SQLITE_TEST
- /*
--** Open the file indicated and write a log of all unfreed memory 
--** allocations into that log.
-+** The list of all registered VFS implementations.
- */
--SQLITE_PRIVATE void sqlite3Memsys5Dump(const char *zFilename){
--  FILE *out;
--  int i, j, n;
--  int nMinLog;
-+static sqlite3_vfs * SQLITE_WSD vfsList = 0;
-+#define vfsList GLOBAL(sqlite3_vfs *, vfsList)
- 
--  if( zFilename==0 || zFilename[0]==0 ){
--    out = stdout;
--  }else{
--    out = fopen(zFilename, "w");
--    if( out==0 ){
--      fprintf(stderr, "** Unable to output memory debug output log: %s **\n",
--                      zFilename);
--      return;
--    }
-+/*
-+** 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){
-+  sqlite3_vfs *pVfs = 0;
-+#if SQLITE_THREADSAFE
-+  sqlite3_mutex *mutex;
-+#endif
-+#ifndef SQLITE_OMIT_AUTOINIT
-+  int rc = sqlite3_initialize();
-+  if( rc ) return 0;
-+#endif
-+#if SQLITE_THREADSAFE
-+  mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
-+#endif
-+  sqlite3_mutex_enter(mutex);
-+  for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){
-+    if( zVfs==0 ) break;
-+    if( strcmp(zVfs, pVfs->zName)==0 ) break;
-   }
--  memsys5Enter();
--  nMinLog = memsys5Log(mem5.szAtom);
--  for(i=0; i<=LOGMAX && i+nMinLog<32; i++){
--    for(n=0, j=mem5.aiFreelist[i]; j>=0; j = MEM5LINK(j)->next, n++){}
--    fprintf(out, "freelist items of size %d: %d\n", mem5.szAtom << i, n);
-+  sqlite3_mutex_leave(mutex);
-+  return pVfs;
-+}
-+
-+/*
-+** Unlink a VFS from the linked list
-+*/
-+static void vfsUnlink(sqlite3_vfs *pVfs){
-+  assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) );
-+  if( pVfs==0 ){
-+    /* No-op */
-+  }else if( vfsList==pVfs ){
-+    vfsList = pVfs->pNext;
-+  }else if( vfsList ){
-+    sqlite3_vfs *p = vfsList;
-+    while( p->pNext && p->pNext!=pVfs ){
-+      p = p->pNext;
-+    }
-+    if( p->pNext==pVfs ){
-+      p->pNext = pVfs->pNext;
-+    }
-   }
--  fprintf(out, "mem5.nAlloc       = %llu\n", mem5.nAlloc);
--  fprintf(out, "mem5.totalAlloc   = %llu\n", mem5.totalAlloc);
--  fprintf(out, "mem5.totalExcess  = %llu\n", mem5.totalExcess);
--  fprintf(out, "mem5.currentOut   = %u\n", mem5.currentOut);
--  fprintf(out, "mem5.currentCount = %u\n", mem5.currentCount);
--  fprintf(out, "mem5.maxOut       = %u\n", mem5.maxOut);
--  fprintf(out, "mem5.maxCount     = %u\n", mem5.maxCount);
--  fprintf(out, "mem5.maxRequest   = %u\n", mem5.maxRequest);
--  memsys5Leave();
--  if( out==stdout ){
--    fflush(stdout);
-+}
-+
-+/*
-+** Register a VFS with the system.  It is harmless to register the same
-+** VFS multiple times.  The new VFS becomes the default if makeDflt is
-+** true.
-+*/
-+SQLITE_API int 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
-+  MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
-+  sqlite3_mutex_enter(mutex);
-+  vfsUnlink(pVfs);
-+  if( makeDflt || vfsList==0 ){
-+    pVfs->pNext = vfsList;
-+    vfsList = pVfs;
-   }else{
--    fclose(out);
-+    pVfs->pNext = vfsList->pNext;
-+    vfsList->pNext = pVfs;
-   }
-+  assert(vfsList);
-+  sqlite3_mutex_leave(mutex);
-+  return SQLITE_OK;
- }
--#endif
- 
- /*
--** This routine is the only routine in this file with external 
--** linkage. It returns a pointer to a static sqlite3_mem_methods
--** struct populated with the memsys5 methods.
-+** Unregister a VFS so that it is no longer accessible.
- */
--SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void){
--  static const sqlite3_mem_methods memsys5Methods = {
--     memsys5Malloc,
--     memsys5Free,
--     memsys5Realloc,
--     memsys5Size,
--     memsys5Roundup,
--     memsys5Init,
--     memsys5Shutdown,
--     0
--  };
--  return &memsys5Methods;
-+SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
-+#if SQLITE_THREADSAFE
-+  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
-+#endif
-+  sqlite3_mutex_enter(mutex);
-+  vfsUnlink(pVfs);
-+  sqlite3_mutex_leave(mutex);
-+  return SQLITE_OK;
- }
- 
--#endif /* SQLITE_ENABLE_MEMSYS5 */
--
--/************** End of mem5.c ************************************************/
--/************** Begin file mutex.c *******************************************/
-+/************** End of os.c **************************************************/
-+/************** Begin file fault.c *******************************************/
- /*
--** 2007 August 14
-+** 2008 Jan 22
- **
- ** The author disclaims copyright to this source code.  In place of
- ** a legal notice, here is a blessing:
-@@ -17715,152 +18517,147 @@
- **    May you share freely, never taking more than you give.
- **
- *************************************************************************
--** This file contains the C functions that implement mutexes.
- **
--** This file contains code that is common across all mutex implementations.
-+** This file contains code to support the concept of "benign" 
-+** malloc failures (when the xMalloc() or xRealloc() method of the
-+** sqlite3_mem_methods structure fails to allocate a block of memory
-+** and returns 0). 
-+**
-+** Most malloc failures are non-benign. After they occur, SQLite
-+** abandons the current operation and returns an error code (usually
-+** SQLITE_NOMEM) to the user. However, sometimes a fault is not necessarily
-+** fatal. For example, if a malloc fails while resizing a hash table, this 
-+** is completely recoverable simply by not carrying out the resize. The 
-+** hash table will continue to function normally.  So a malloc failure 
-+** during a hash table resize is a benign fault.
- */
- 
--#if defined(SQLITE_DEBUG) && !defined(SQLITE_MUTEX_OMIT)
--/*
--** For debugging purposes, record when the mutex subsystem is initialized
--** and uninitialized so that we can assert() if there is an attempt to
--** allocate a mutex while the system is uninitialized.
--*/
--static SQLITE_WSD int mutexIsInit = 0;
--#endif /* SQLITE_DEBUG */
- 
-+#ifndef SQLITE_OMIT_BUILTIN_TEST
- 
--#ifndef SQLITE_MUTEX_OMIT
- /*
--** Initialize the mutex system.
-+** Global variables.
- */
--SQLITE_PRIVATE int sqlite3MutexInit(void){ 
--  int rc = SQLITE_OK;
--  if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){
--    /* If the xMutexAlloc method has not been set, then the user did not
--    ** install a mutex implementation via sqlite3_config() prior to 
--    ** sqlite3_initialize() being called. This block copies pointers to
--    ** the default implementation into the sqlite3GlobalConfig structure.
--    */
--    sqlite3_mutex_methods const *pFrom;
--    sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex;
--
--    if( sqlite3GlobalConfig.bCoreMutex ){
--      pFrom = sqlite3DefaultMutex();
--    }else{
--      pFrom = sqlite3NoopMutex();
--    }
--    memcpy(pTo, pFrom, offsetof(sqlite3_mutex_methods, xMutexAlloc));
--    memcpy(&pTo->xMutexFree, &pFrom->xMutexFree,
--           sizeof(*pTo) - offsetof(sqlite3_mutex_methods, xMutexFree));
--    pTo->xMutexAlloc = pFrom->xMutexAlloc;
--  }
--  rc = sqlite3GlobalConfig.mutex.xMutexInit();
-+typedef struct BenignMallocHooks BenignMallocHooks;
-+static SQLITE_WSD struct BenignMallocHooks {
-+  void (*xBenignBegin)(void);
-+  void (*xBenignEnd)(void);
-+} sqlite3Hooks = { 0, 0 };
- 
--#ifdef SQLITE_DEBUG
--  GLOBAL(int, mutexIsInit) = 1;
-+/* The "wsdHooks" macro will resolve to the appropriate BenignMallocHooks
-+** structure.  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, wsdHooks can refer directly
-+** to the "sqlite3Hooks" state vector declared above.
-+*/
-+#ifdef SQLITE_OMIT_WSD
-+# define wsdHooksInit \
-+  BenignMallocHooks *x = &GLOBAL(BenignMallocHooks,sqlite3Hooks)
-+# define wsdHooks x[0]
-+#else
-+# define wsdHooksInit
-+# define wsdHooks sqlite3Hooks
- #endif
- 
--  return rc;
--}
- 
- /*
--** Shutdown the mutex system. This call frees resources allocated by
--** sqlite3MutexInit().
-+** Register hooks to call when sqlite3BeginBenignMalloc() and
-+** sqlite3EndBenignMalloc() are called, respectively.
- */
--SQLITE_PRIVATE int sqlite3MutexEnd(void){
--  int rc = SQLITE_OK;
--  if( sqlite3GlobalConfig.mutex.xMutexEnd ){
--    rc = sqlite3GlobalConfig.mutex.xMutexEnd();
--  }
--
--#ifdef SQLITE_DEBUG
--  GLOBAL(int, mutexIsInit) = 0;
--#endif
--
--  return rc;
-+SQLITE_PRIVATE void sqlite3BenignMallocHooks(
-+  void (*xBenignBegin)(void),
-+  void (*xBenignEnd)(void)
-+){
-+  wsdHooksInit;
-+  wsdHooks.xBenignBegin = xBenignBegin;
-+  wsdHooks.xBenignEnd = xBenignEnd;
- }
- 
- /*
--** Retrieve a pointer to a static mutex or allocate a new dynamic one.
-+** This (sqlite3EndBenignMalloc()) is called by SQLite code to indicate that
-+** subsequent malloc failures are benign. A call to sqlite3EndBenignMalloc()
-+** indicates that subsequent malloc failures are non-benign.
- */
--SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){
--#ifndef SQLITE_OMIT_AUTOINIT
--  if( sqlite3_initialize() ) return 0;
--#endif
--  return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
--}
--
--SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){
--  if( !sqlite3GlobalConfig.bCoreMutex ){
--    return 0;
-+SQLITE_PRIVATE void sqlite3BeginBenignMalloc(void){
-+  wsdHooksInit;
-+  if( wsdHooks.xBenignBegin ){
-+    wsdHooks.xBenignBegin();
-   }
--  assert( GLOBAL(int, mutexIsInit) );
--  return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
- }
--
--/*
--** Free a dynamic mutex.
--*/
--SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *p){
--  if( p ){
--    sqlite3GlobalConfig.mutex.xMutexFree(p);
-+SQLITE_PRIVATE void sqlite3EndBenignMalloc(void){
-+  wsdHooksInit;
-+  if( wsdHooks.xBenignEnd ){
-+    wsdHooks.xBenignEnd();
-   }
- }
- 
-+#endif   /* #ifndef SQLITE_OMIT_BUILTIN_TEST */
-+
-+/************** End of fault.c ***********************************************/
-+/************** Begin file mem0.c ********************************************/
- /*
--** Obtain the mutex p. If some other thread already has the mutex, block
--** until it can be obtained.
-+** 2008 October 28
-+**
-+** 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 a no-op memory allocation drivers for use when
-+** SQLITE_ZERO_MALLOC is defined.  The allocation drivers implemented
-+** here always fail.  SQLite will not operate with these drivers.  These
-+** are merely placeholders.  Real drivers must be substituted using
-+** sqlite3_config() before SQLite will operate.
- */
--SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex *p){
--  if( p ){
--    sqlite3GlobalConfig.mutex.xMutexEnter(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.
-+** This version of the memory allocator is the default.  It is
-+** used when no other memory allocator is specified using compile-time
-+** macros.
- */
--SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){
--  int rc = SQLITE_OK;
--  if( p ){
--    return sqlite3GlobalConfig.mutex.xMutexTry(p);
--  }
--  return rc;
--}
-+#ifdef SQLITE_ZERO_MALLOC
- 
- /*
--** The sqlite3_mutex_leave() routine exits a mutex that was previously
--** entered by the same thread.  The behavior is undefined if the mutex 
--** is not currently entered. If a NULL pointer is passed as an argument
--** this function is a no-op.
-+** No-op versions of all memory allocation routines
- */
--SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){
--  if( p ){
--    sqlite3GlobalConfig.mutex.xMutexLeave(p);
--  }
--}
-+static void *sqlite3MemMalloc(int nByte){ return 0; }
-+static void sqlite3MemFree(void *pPrior){ return; }
-+static void *sqlite3MemRealloc(void *pPrior, int nByte){ return 0; }
-+static int sqlite3MemSize(void *pPrior){ return 0; }
-+static int sqlite3MemRoundup(int n){ return n; }
-+static int sqlite3MemInit(void *NotUsed){ return SQLITE_OK; }
-+static void sqlite3MemShutdown(void *NotUsed){ return; }
- 
--#ifndef NDEBUG
- /*
--** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
--** intended for use inside assert() statements.
-+** This routine is the only routine in this file with external linkage.
-+**
-+** Populate the low-level memory allocation function pointers in
-+** sqlite3GlobalConfig.m with pointers to the routines in this file.
- */
--SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){
--  return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p);
--}
--SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){
--  return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
-+SQLITE_PRIVATE void sqlite3MemSetDefault(void){
-+  static const sqlite3_mem_methods defaultMethods = {
-+     sqlite3MemMalloc,
-+     sqlite3MemFree,
-+     sqlite3MemRealloc,
-+     sqlite3MemSize,
-+     sqlite3MemRoundup,
-+     sqlite3MemInit,
-+     sqlite3MemShutdown,
-+     0
-+  };
-+  sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
- }
--#endif
- 
--#endif /* !defined(SQLITE_MUTEX_OMIT) */
-+#endif /* SQLITE_ZERO_MALLOC */
- 
--/************** End of mutex.c ***********************************************/
--/************** Begin file mutex_noop.c **************************************/
-+/************** End of mem0.c ************************************************/
-+/************** Begin file mem1.c ********************************************/
- /*
--** 2008 October 07
-+** 2007 August 14
- **
- ** The author disclaims copyright to this source code.  In place of
- ** a legal notice, here is a blessing:
-@@ -17870,205 +18667,278 @@
- **    May you share freely, never taking more than you give.
- **
- *************************************************************************
--** This file contains the C functions that implement mutexes.
- **
--** This implementation in this file does not provide any mutual
--** exclusion and is thus suitable for use only in applications
--** that use SQLite in a single thread.  The routines defined
--** here are place-holders.  Applications can substitute working
--** mutex routines at start-time using the
-+** This file contains low-level memory allocation drivers for when
-+** SQLite will use the standard C-library malloc/realloc/free interface
-+** to obtain the memory it needs.
- **
--**     sqlite3_config(SQLITE_CONFIG_MUTEX,...)
-+** This file contains implementations of the low-level memory allocation
-+** routines specified in the sqlite3_mem_methods object.  The content of
-+** this file is only used if SQLITE_SYSTEM_MALLOC is defined.  The
-+** SQLITE_SYSTEM_MALLOC macro is defined automatically if neither the
-+** SQLITE_MEMDEBUG nor the SQLITE_WIN32_MALLOC macros are defined.  The
-+** default configuration is to use memory allocation routines in this
-+** file.
- **
--** interface.
-+** C-preprocessor macro summary:
- **
--** If compiled with SQLITE_DEBUG, then additional logic is inserted
--** that does error checking on mutexes to make sure they are being
--** called correctly.
-+**    HAVE_MALLOC_USABLE_SIZE     The configure script sets this symbol if
-+**                                the malloc_usable_size() interface exists
-+**                                on the target platform.  Or, this symbol
-+**                                can be set manually, if desired.
-+**                                If an equivalent interface exists by
-+**                                a different name, using a separate -D
-+**                                option to rename it.
-+**
-+**    SQLITE_WITHOUT_ZONEMALLOC   Some older macs lack support for the zone
-+**                                memory allocator.  Set this symbol to enable
-+**                                building on older macs.
-+**
-+**    SQLITE_WITHOUT_MSIZE        Set this symbol to disable the use of
-+**                                _msize() on windows systems.  This might
-+**                                be necessary when compiling for Delphi,
-+**                                for example.
- */
- 
--#ifndef SQLITE_MUTEX_OMIT
-+/*
-+** This version of the memory allocator is the default.  It is
-+** used when no other memory allocator is specified using compile-time
-+** macros.
-+*/
-+#ifdef SQLITE_SYSTEM_MALLOC
- 
--#ifndef SQLITE_DEBUG
- /*
--** Stub routines for all mutex methods.
--**
--** This routines provide no mutual exclusion or error checking.
-+** The MSVCRT has malloc_usable_size() but it is called _msize().
-+** The use of _msize() is automatic, but can be disabled by compiling
-+** with -DSQLITE_WITHOUT_MSIZE
- */
--static int noopMutexInit(void){ return SQLITE_OK; }
--static int noopMutexEnd(void){ return SQLITE_OK; }
--static sqlite3_mutex *noopMutexAlloc(int id){ 
--  UNUSED_PARAMETER(id);
--  return (sqlite3_mutex*)8; 
--}
--static void noopMutexFree(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; }
--static void noopMutexEnter(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; }
--static int noopMutexTry(sqlite3_mutex *p){
--  UNUSED_PARAMETER(p);
--  return SQLITE_OK;
--}
--static void noopMutexLeave(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; }
-+#if defined(_MSC_VER) && !defined(SQLITE_WITHOUT_MSIZE)
-+# define SQLITE_MALLOCSIZE _msize
-+#endif
- 
--SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void){
--  static const sqlite3_mutex_methods sMutex = {
--    noopMutexInit,
--    noopMutexEnd,
--    noopMutexAlloc,
--    noopMutexFree,
--    noopMutexEnter,
--    noopMutexTry,
--    noopMutexLeave,
-+#if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC)
- 
--    0,
--    0,
--  };
-+/*
-+** Use the zone allocator available on apple products unless the
-+** SQLITE_WITHOUT_ZONEMALLOC symbol is defined.
-+*/
-+#include <sys/sysctl.h>
-+#include <malloc/malloc.h>
-+#include <libkern/OSAtomic.h>
-+static malloc_zone_t* _sqliteZone_;
-+#define SQLITE_MALLOC(x) malloc_zone_malloc(_sqliteZone_, (x))
-+#define SQLITE_FREE(x) malloc_zone_free(_sqliteZone_, (x));
-+#define SQLITE_REALLOC(x,y) malloc_zone_realloc(_sqliteZone_, (x), (y))
-+#define SQLITE_MALLOCSIZE(x) \
-+        (_sqliteZone_ ? _sqliteZone_->size(_sqliteZone_,x) : malloc_size(x))
- 
--  return &sMutex;
--}
--#endif /* !SQLITE_DEBUG */
-+#else /* if not __APPLE__ */
- 
--#ifdef SQLITE_DEBUG
- /*
--** In this implementation, error checking is provided for testing
--** and debugging purposes.  The mutexes still do not provide any
--** mutual exclusion.
-+** Use standard C library malloc and free on non-Apple systems.  
-+** Also used by Apple systems if SQLITE_WITHOUT_ZONEMALLOC is defined.
- */
-+#define SQLITE_MALLOC(x)    malloc(x)
-+#define SQLITE_FREE(x)      free(x)
-+#define SQLITE_REALLOC(x,y) realloc((x),(y))
-+
-+#if (defined(_MSC_VER) && !defined(SQLITE_WITHOUT_MSIZE)) \
-+      || (defined(HAVE_MALLOC_H) && defined(HAVE_MALLOC_USABLE_SIZE))
-+# include <malloc.h>    /* Needed for malloc_usable_size on linux */
-+#endif
-+#ifdef HAVE_MALLOC_USABLE_SIZE
-+# ifndef SQLITE_MALLOCSIZE
-+#  define SQLITE_MALLOCSIZE(x) malloc_usable_size(x)
-+# endif
-+#else
-+# undef SQLITE_MALLOCSIZE
-+#endif
-+
-+#endif /* __APPLE__ or not __APPLE__ */
- 
- /*
--** The mutex object
-+** Like malloc(), but remember the size of the allocation
-+** so that we can find it later using sqlite3MemSize().
-+**
-+** For this low-level routine, we are guaranteed that nByte>0 because
-+** cases of nByte<=0 will be intercepted and dealt with by higher level
-+** routines.
- */
--typedef struct sqlite3_debug_mutex {
--  int id;     /* The mutex type */
--  int cnt;    /* Number of entries without a matching leave */
--} sqlite3_debug_mutex;
-+static void *sqlite3MemMalloc(int nByte){
-+#ifdef SQLITE_MALLOCSIZE
-+  void *p = SQLITE_MALLOC( nByte );
-+  if( p==0 ){
-+    testcase( sqlite3GlobalConfig.xLog!=0 );
-+    sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
-+  }
-+  return p;
-+#else
-+  sqlite3_int64 *p;
-+  assert( nByte>0 );
-+  nByte = ROUND8(nByte);
-+  p = SQLITE_MALLOC( nByte+8 );
-+  if( p ){
-+    p[0] = nByte;
-+    p++;
-+  }else{
-+    testcase( sqlite3GlobalConfig.xLog!=0 );
-+    sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
-+  }
-+  return (void *)p;
-+#endif
-+}
- 
- /*
--** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
--** intended for use inside assert() statements.
-+** Like free() but works for allocations obtained from sqlite3MemMalloc()
-+** or sqlite3MemRealloc().
-+**
-+** For this low-level routine, we already know that pPrior!=0 since
-+** cases where pPrior==0 will have been intecepted and dealt with
-+** by higher-level routines.
- */
--static int debugMutexHeld(sqlite3_mutex *pX){
--  sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
--  return p==0 || p->cnt>0;
--}
--static int debugMutexNotheld(sqlite3_mutex *pX){
--  sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
--  return p==0 || p->cnt==0;
-+static void sqlite3MemFree(void *pPrior){
-+#ifdef SQLITE_MALLOCSIZE
-+  SQLITE_FREE(pPrior);
-+#else
-+  sqlite3_int64 *p = (sqlite3_int64*)pPrior;
-+  assert( pPrior!=0 );
-+  p--;
-+  SQLITE_FREE(p);
-+#endif
- }
- 
- /*
--** Initialize and deinitialize the mutex subsystem.
-+** Report the allocated size of a prior return from xMalloc()
-+** or xRealloc().
- */
--static int debugMutexInit(void){ return SQLITE_OK; }
--static int debugMutexEnd(void){ return SQLITE_OK; }
-+static int sqlite3MemSize(void *pPrior){
-+#ifdef SQLITE_MALLOCSIZE
-+  return pPrior ? (int)SQLITE_MALLOCSIZE(pPrior) : 0;
-+#else
-+  sqlite3_int64 *p;
-+  if( pPrior==0 ) return 0;
-+  p = (sqlite3_int64*)pPrior;
-+  p--;
-+  return (int)p[0];
-+#endif
-+}
- 
- /*
--** 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. 
-+** Like realloc().  Resize an allocation previously obtained from
-+** sqlite3MemMalloc().
-+**
-+** 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
-+** cases where nByte<=0 will have been intercepted by higher-level
-+** routines and redirected to xFree.
- */
--static sqlite3_mutex *debugMutexAlloc(int id){
--  static sqlite3_debug_mutex aStatic[6];
--  sqlite3_debug_mutex *pNew = 0;
--  switch( id ){
--    case SQLITE_MUTEX_FAST:
--    case SQLITE_MUTEX_RECURSIVE: {
--      pNew = sqlite3Malloc(sizeof(*pNew));
--      if( pNew ){
--        pNew->id = id;
--        pNew->cnt = 0;
--      }
--      break;
--    }
--    default: {
--      assert( id-2 >= 0 );
--      assert( id-2 < (int)(sizeof(aStatic)/sizeof(aStatic[0])) );
--      pNew = &aStatic[id-2];
--      pNew->id = id;
--      break;
--    }
-+static void *sqlite3MemRealloc(void *pPrior, int nByte){
-+#ifdef SQLITE_MALLOCSIZE
-+  void *p = SQLITE_REALLOC(pPrior, nByte);
-+  if( p==0 ){
-+    testcase( sqlite3GlobalConfig.xLog!=0 );
-+    sqlite3_log(SQLITE_NOMEM,
-+      "failed memory resize %u to %u bytes",
-+      SQLITE_MALLOCSIZE(pPrior), nByte);
-   }
--  return (sqlite3_mutex*)pNew;
-+  return p;
-+#else
-+  sqlite3_int64 *p = (sqlite3_int64*)pPrior;
-+  assert( pPrior!=0 && nByte>0 );
-+  assert( nByte==ROUND8(nByte) ); /* EV: R-46199-30249 */
-+  p--;
-+  p = SQLITE_REALLOC(p, nByte+8 );
-+  if( p ){
-+    p[0] = nByte;
-+    p++;
-+  }else{
-+    testcase( sqlite3GlobalConfig.xLog!=0 );
-+    sqlite3_log(SQLITE_NOMEM,
-+      "failed memory resize %u to %u bytes",
-+      sqlite3MemSize(pPrior), nByte);
-+  }
-+  return (void*)p;
-+#endif
- }
- 
- /*
--** This routine deallocates a previously allocated mutex.
-+** Round up a request size to the next valid allocation size.
- */
--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);
-+static int sqlite3MemRoundup(int n){
-+  return ROUND8(n);
- }
- 
- /*
--** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
--** to enter a mutex.  If another thread is already within the mutex,
--** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
--** 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,
--** 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.
-+** Initialize this module.
- */
--static void debugMutexEnter(sqlite3_mutex *pX){
--  sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
--  assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
--  p->cnt++;
--}
--static int debugMutexTry(sqlite3_mutex *pX){
--  sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
--  assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
--  p->cnt++;
-+static int sqlite3MemInit(void *NotUsed){
-+#if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC)
-+  int cpuCount;
-+  size_t len;
-+  if( _sqliteZone_ ){
-+    return SQLITE_OK;
-+  }
-+  len = sizeof(cpuCount);
-+  /* One usually wants to use hw.acctivecpu for MT decisions, but not here */
-+  sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0);
-+  if( cpuCount>1 ){
-+    /* defer MT decisions to system malloc */
-+    _sqliteZone_ = malloc_default_zone();
-+  }else{
-+    /* only 1 core, use our own zone to contention over global locks, 
-+    ** e.g. we have our own dedicated locks */
-+    bool success;
-+    malloc_zone_t* newzone = malloc_create_zone(4096, 0);
-+    malloc_set_zone_name(newzone, "Sqlite_Heap");
-+    do{
-+      success = OSAtomicCompareAndSwapPtrBarrier(NULL, newzone, 
-+                                 (void * volatile *)&_sqliteZone_);
-+    }while(!_sqliteZone_);
-+    if( !success ){
-+      /* somebody registered a zone first */
-+      malloc_destroy_zone(newzone);
-+    }
-+  }
-+#endif
-+  UNUSED_PARAMETER(NotUsed);
-   return SQLITE_OK;
- }
- 
- /*
--** The sqlite3_mutex_leave() routine exits a mutex that was
--** previously entered by the same thread.  The behavior
--** is undefined if the mutex is not currently entered or
--** is not currently allocated.  SQLite will never do either.
-+** Deinitialize this module.
- */
--static void debugMutexLeave(sqlite3_mutex *pX){
--  sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
--  assert( debugMutexHeld(pX) );
--  p->cnt--;
--  assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
--}
--
--SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void){
--  static const sqlite3_mutex_methods sMutex = {
--    debugMutexInit,
--    debugMutexEnd,
--    debugMutexAlloc,
--    debugMutexFree,
--    debugMutexEnter,
--    debugMutexTry,
--    debugMutexLeave,
--
--    debugMutexHeld,
--    debugMutexNotheld
--  };
--
--  return &sMutex;
-+static void sqlite3MemShutdown(void *NotUsed){
-+  UNUSED_PARAMETER(NotUsed);
-+  return;
- }
--#endif /* SQLITE_DEBUG */
- 
- /*
--** If compiled with SQLITE_MUTEX_NOOP, then the no-op mutex implementation
--** is used regardless of the run-time threadsafety setting.
-+** This routine is the only routine in this file with external linkage.
-+**
-+** Populate the low-level memory allocation function pointers in
-+** sqlite3GlobalConfig.m with pointers to the routines in this file.
- */
--#ifdef SQLITE_MUTEX_NOOP
--SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
--  return sqlite3NoopMutex();
-+SQLITE_PRIVATE void sqlite3MemSetDefault(void){
-+  static const sqlite3_mem_methods defaultMethods = {
-+     sqlite3MemMalloc,
-+     sqlite3MemFree,
-+     sqlite3MemRealloc,
-+     sqlite3MemSize,
-+     sqlite3MemRoundup,
-+     sqlite3MemInit,
-+     sqlite3MemShutdown,
-+     0
-+  };
-+  sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
- }
--#endif /* defined(SQLITE_MUTEX_NOOP) */
--#endif /* !defined(SQLITE_MUTEX_OMIT) */
- 
--/************** End of mutex_noop.c ******************************************/
--/************** Begin file mutex_unix.c **************************************/
-+#endif /* SQLITE_SYSTEM_MALLOC */
-+
-+/************** End of mem1.c ************************************************/
-+/************** Begin file mem2.c ********************************************/
- /*
--** 2007 August 28
-+** 2007 August 15
- **
- ** The author disclaims copyright to this source code.  In place of
- ** a legal notice, here is a blessing:
-@@ -18078,694 +18948,527 @@
- **    May you share freely, never taking more than you give.
- **
- *************************************************************************
--** This file contains the C functions that implement mutexes for pthreads
-+**
-+** This file contains low-level memory allocation drivers for when
-+** SQLite will use the standard C-library malloc/realloc/free interface
-+** to obtain the memory it needs while adding lots of additional debugging
-+** information to each allocation in order to help detect and fix memory
-+** leaks and memory usage errors.
-+**
-+** This file contains implementations of the low-level memory allocation
-+** routines specified in the sqlite3_mem_methods object.
- */
- 
- /*
--** The code in this file is only used if we are compiling threadsafe
--** under unix with pthreads.
--**
--** Note that this implementation requires a version of pthreads that
--** supports recursive mutexes.
-+** This version of the memory allocator is used only if the
-+** SQLITE_MEMDEBUG macro is defined
- */
--#ifdef SQLITE_MUTEX_PTHREADS
--
--#include <pthread.h>
-+#ifdef SQLITE_MEMDEBUG
- 
- /*
--** The sqlite3_mutex.id, sqlite3_mutex.nRef, and sqlite3_mutex.owner fields
--** are necessary under two condidtions:  (1) Debug builds and (2) using
--** home-grown mutexes.  Encapsulate these conditions into a single #define.
-+** The backtrace functionality is only available with GLIBC
- */
--#if defined(SQLITE_DEBUG) || defined(SQLITE_HOMEGROWN_RECURSIVE_MUTEX)
--# define SQLITE_MUTEX_NREF 1
--#else
--# define SQLITE_MUTEX_NREF 0
--#endif
--
--/*
--** Each recursive mutex is an instance of the following structure.
--*/
--struct sqlite3_mutex {
--  pthread_mutex_t mutex;     /* Mutex controlling the lock */
--#if SQLITE_MUTEX_NREF
--  int id;                    /* Mutex type */
--  volatile int nRef;         /* Number of entrances */
--  volatile pthread_t owner;  /* Thread that is within this mutex */
--  int trace;                 /* True to trace changes */
--#endif
--};
--#if SQLITE_MUTEX_NREF
--#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0, (pthread_t)0, 0 }
-+#ifdef __GLIBC__
-+  extern int backtrace(void**,int);
-+  extern void backtrace_symbols_fd(void*const*,int,int);
- #else
--#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }
-+# define backtrace(A,B) 1
-+# define backtrace_symbols_fd(A,B,C)
- #endif
-+/* #include <stdio.h> */
- 
- /*
--** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
--** intended for use only inside assert() statements.  On some platforms,
--** there might be race conditions that can cause these routines to
--** deliver incorrect results.  In particular, if pthread_equal() is
--** not an atomic operation, then these routines might delivery
--** incorrect results.  On most platforms, pthread_equal() is a 
--** comparison of two integers and is therefore atomic.  But we are
--** told that HPUX is not such a platform.  If so, then these routines
--** will not always work correctly on HPUX.
-+** Each memory allocation looks like this:
- **
--** On those platforms where pthread_equal() is not atomic, SQLite
--** should be compiled without -DSQLITE_DEBUG and with -DNDEBUG to
--** make sure no assert() statements are evaluated and hence these
--** routines are never called.
--*/
--#if !defined(NDEBUG) || defined(SQLITE_DEBUG)
--static int pthreadMutexHeld(sqlite3_mutex *p){
--  return (p->nRef!=0 && pthread_equal(p->owner, pthread_self()));
--}
--static int pthreadMutexNotheld(sqlite3_mutex *p){
--  return p->nRef==0 || pthread_equal(p->owner, pthread_self())==0;
--}
--#endif
--
--/*
--** Initialize and deinitialize the mutex subsystem.
-+**  ------------------------------------------------------------------------
-+**  | Title |  backtrace pointers |  MemBlockHdr |  allocation |  EndGuard |
-+**  ------------------------------------------------------------------------
-+**
-+** The application code sees only a pointer to the allocation.  We have
-+** to back up from the allocation pointer to find the MemBlockHdr.  The
-+** MemBlockHdr tells us the size of the allocation and the number of
-+** backtrace pointers.  There is also a guard word at the end of the
-+** MemBlockHdr.
- */
--static int pthreadMutexInit(void){ return SQLITE_OK; }
--static int pthreadMutexEnd(void){ return SQLITE_OK; }
-+struct MemBlockHdr {
-+  i64 iSize;                          /* Size of this allocation */
-+  struct MemBlockHdr *pNext, *pPrev;  /* Linked list of all unfreed memory */
-+  char nBacktrace;                    /* Number of backtraces on this alloc */
-+  char nBacktraceSlots;               /* Available backtrace slots */
-+  u8 nTitle;                          /* Bytes of title; includes '\0' */
-+  u8 eType;                           /* Allocation type code */
-+  int iForeGuard;                     /* Guard word for sanity */
-+};
- 
- /*
--** 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:
--**
--** <ul>
--** <li>  SQLITE_MUTEX_FAST
--** <li>  SQLITE_MUTEX_RECURSIVE
--** <li>  SQLITE_MUTEX_STATIC_MASTER
--** <li>  SQLITE_MUTEX_STATIC_MEM
--** <li>  SQLITE_MUTEX_STATIC_MEM2
--** <li>  SQLITE_MUTEX_STATIC_PRNG
--** <li>  SQLITE_MUTEX_STATIC_LRU
--** <li>  SQLITE_MUTEX_STATIC_PMEM
--** </ul>
--**
--** The first two constants cause sqlite3_mutex_alloc() to create
--** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
--** 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.  But 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() each return
--** a pointer to a static preexisting mutex.  Six 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
--** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
--** SQLITE_MUTEX_RECURSIVE.
--**
--** 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 
--** mutex types, the same mutex is returned on every call that has
--** the same type number.
-+** Guard words
- */
--static sqlite3_mutex *pthreadMutexAlloc(int iType){
--  static sqlite3_mutex staticMutexes[] = {
--    SQLITE3_MUTEX_INITIALIZER,
--    SQLITE3_MUTEX_INITIALIZER,
--    SQLITE3_MUTEX_INITIALIZER,
--    SQLITE3_MUTEX_INITIALIZER,
--    SQLITE3_MUTEX_INITIALIZER,
--    SQLITE3_MUTEX_INITIALIZER
--  };
--  sqlite3_mutex *p;
--  switch( iType ){
--    case SQLITE_MUTEX_RECURSIVE: {
--      p = sqlite3MallocZero( sizeof(*p) );
--      if( p ){
--#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
--        /* If recursive mutexes are not available, we will have to
--        ** build our own.  See below. */
--        pthread_mutex_init(&p->mutex, 0);
--#else
--        /* Use a recursive mutex if it is available */
--        pthread_mutexattr_t recursiveAttr;
--        pthread_mutexattr_init(&recursiveAttr);
--        pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE);
--        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;
--#endif
--      break;
--    }
--  }
--  return p;
--}
--
-+#define FOREGUARD 0x80F5E153
-+#define REARGUARD 0xE4676B53
- 
- /*
--** This routine deallocates a previously
--** allocated mutex.  SQLite is careful to deallocate every
--** mutex that it allocates.
-+** Number of malloc size increments to track.
- */
--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);
--}
-+#define NCSIZE  1000
- 
- /*
--** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
--** to enter a mutex.  If another thread is already within the mutex,
--** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
--** 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,
--** 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.
-+** All of the static variables used by this module are collected
-+** into a single structure named "mem".  This is to keep the
-+** static variables organized and to reduce namespace pollution
-+** when this module is combined with other in the amalgamation.
- */
--static void pthreadMutexEnter(sqlite3_mutex *p){
--  assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) );
-+static struct {
-+  
-+  /*
-+  ** Mutex to control access to the memory allocation subsystem.
-+  */
-+  sqlite3_mutex *mutex;
- 
--#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
--  /* If recursive mutexes are not available, then we have to grow
--  ** our own.  This implementation assumes that pthread_equal()
--  ** is atomic - that it cannot be deceived into thinking self
--  ** and p->owner are equal if p->owner changes between two values
--  ** that are not equal to self while the comparison is taking place.
--  ** This implementation also assumes a coherent cache - that 
--  ** separate processes cannot read different values from the same
--  ** address at the same time.  If either of these two conditions
--  ** are not met, then the mutexes will fail and problems will result.
-+  /*
-+  ** Head and tail of a linked list of all outstanding allocations
-   */
--  {
--    pthread_t self = pthread_self();
--    if( p->nRef>0 && pthread_equal(p->owner, self) ){
--      p->nRef++;
--    }else{
--      pthread_mutex_lock(&p->mutex);
--      assert( p->nRef==0 );
--      p->owner = self;
--      p->nRef = 1;
--    }
--  }
--#else
--  /* Use the built-in recursive mutexes if they are available.
-+  struct MemBlockHdr *pFirst;
-+  struct MemBlockHdr *pLast;
-+  
-+  /*
-+  ** The number of levels of backtrace to save in new allocations.
-   */
--  pthread_mutex_lock(&p->mutex);
--#if SQLITE_MUTEX_NREF
--  assert( p->nRef>0 || p->owner==0 );
--  p->owner = pthread_self();
--  p->nRef++;
--#endif
--#endif
-+  int nBacktrace;
-+  void (*xBacktrace)(int, int, void **);
- 
--#ifdef SQLITE_DEBUG
--  if( p->trace ){
--    printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
--  }
--#endif
--}
--static int pthreadMutexTry(sqlite3_mutex *p){
--  int rc;
--  assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) );
-+  /*
-+  ** Title text to insert in front of each block
-+  */
-+  int nTitle;        /* Bytes of zTitle to save.  Includes '\0' and padding */
-+  char zTitle[100];  /* The title text */
- 
--#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
--  /* If recursive mutexes are not available, then we have to grow
--  ** our own.  This implementation assumes that pthread_equal()
--  ** is atomic - that it cannot be deceived into thinking self
--  ** and p->owner are equal if p->owner changes between two values
--  ** that are not equal to self while the comparison is taking place.
--  ** This implementation also assumes a coherent cache - that 
--  ** separate processes cannot read different values from the same
--  ** address at the same time.  If either of these two conditions
--  ** are not met, then the mutexes will fail and problems will result.
-+  /* 
-+  ** sqlite3MallocDisallow() increments the following counter.
-+  ** sqlite3MallocAllow() decrements it.
-   */
--  {
--    pthread_t self = pthread_self();
--    if( p->nRef>0 && pthread_equal(p->owner, self) ){
--      p->nRef++;
--      rc = SQLITE_OK;
--    }else if( pthread_mutex_trylock(&p->mutex)==0 ){
--      assert( p->nRef==0 );
--      p->owner = self;
--      p->nRef = 1;
--      rc = SQLITE_OK;
--    }else{
--      rc = SQLITE_BUSY;
--    }
--  }
--#else
--  /* Use the built-in recursive mutexes if they are available.
-+  int disallow; /* Do not allow memory allocation */
-+
-+  /*
-+  ** Gather statistics on the sizes of memory allocations.
-+  ** nAlloc[i] is the number of allocation attempts of i*8
-+  ** bytes.  i==NCSIZE is the number of allocation attempts for
-+  ** sizes more than NCSIZE*8 bytes.
-   */
--  if( pthread_mutex_trylock(&p->mutex)==0 ){
--#if SQLITE_MUTEX_NREF
--    p->owner = pthread_self();
--    p->nRef++;
--#endif
--    rc = SQLITE_OK;
--  }else{
--    rc = SQLITE_BUSY;
--  }
--#endif
-+  int nAlloc[NCSIZE];      /* Total number of allocations */
-+  int nCurrent[NCSIZE];    /* Current number of allocations */
-+  int mxCurrent[NCSIZE];   /* Highwater mark for nCurrent */
-+
-+} mem;
- 
--#ifdef SQLITE_DEBUG
--  if( rc==SQLITE_OK && p->trace ){
--    printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
--  }
--#endif
--  return rc;
--}
- 
- /*
--** The sqlite3_mutex_leave() routine exits a mutex that was
--** previously entered by the same thread.  The behavior
--** is undefined if the mutex is not currently entered or
--** is not currently allocated.  SQLite will never do either.
-+** Adjust memory usage statistics
- */
--static void pthreadMutexLeave(sqlite3_mutex *p){
--  assert( pthreadMutexHeld(p) );
--#if SQLITE_MUTEX_NREF
--  p->nRef--;
--  if( p->nRef==0 ) p->owner = 0;
--#endif
--  assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
--
--#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
--  if( p->nRef==0 ){
--    pthread_mutex_unlock(&p->mutex);
-+static void adjustStats(int iSize, int increment){
-+  int i = ROUND8(iSize)/8;
-+  if( i>NCSIZE-1 ){
-+    i = NCSIZE - 1;
-   }
--#else
--  pthread_mutex_unlock(&p->mutex);
--#endif
--
--#ifdef SQLITE_DEBUG
--  if( p->trace ){
--    printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
-+  if( increment>0 ){
-+    mem.nAlloc[i]++;
-+    mem.nCurrent[i]++;
-+    if( mem.nCurrent[i]>mem.mxCurrent[i] ){
-+      mem.mxCurrent[i] = mem.nCurrent[i];
-+    }
-+  }else{
-+    mem.nCurrent[i]--;
-+    assert( mem.nCurrent[i]>=0 );
-   }
--#endif
--}
--
--SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
--  static const sqlite3_mutex_methods sMutex = {
--    pthreadMutexInit,
--    pthreadMutexEnd,
--    pthreadMutexAlloc,
--    pthreadMutexFree,
--    pthreadMutexEnter,
--    pthreadMutexTry,
--    pthreadMutexLeave,
--#ifdef SQLITE_DEBUG
--    pthreadMutexHeld,
--    pthreadMutexNotheld
--#else
--    0,
--    0
--#endif
--  };
--
--  return &sMutex;
- }
- 
--#endif /* SQLITE_MUTEX_PTHREADS */
--
--/************** End of mutex_unix.c ******************************************/
--/************** Begin file mutex_w32.c ***************************************/
- /*
--** 2007 August 14
--**
--** 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.
-+** Given an allocation, find the MemBlockHdr for that allocation.
- **
--*************************************************************************
--** This file contains the C functions that implement mutexes for win32
-+** This routine checks the guards at either end of the allocation and
-+** if they are incorrect it asserts.
- */
-+static struct MemBlockHdr *sqlite3MemsysGetHeader(void *pAllocation){
-+  struct MemBlockHdr *p;
-+  int *pInt;
-+  u8 *pU8;
-+  int nReserve;
- 
--/*
--** The code in this file is only used if we are compiling multithreaded
--** on a win32 system.
--*/
--#ifdef SQLITE_MUTEX_W32
-+  p = (struct MemBlockHdr*)pAllocation;
-+  p--;
-+  assert( p->iForeGuard==(int)FOREGUARD );
-+  nReserve = ROUND8(p->iSize);
-+  pInt = (int*)pAllocation;
-+  pU8 = (u8*)pAllocation;
-+  assert( pInt[nReserve/sizeof(int)]==(int)REARGUARD );
-+  /* This checks any of the "extra" bytes allocated due
-+  ** to rounding up to an 8 byte boundary to ensure 
-+  ** they haven't been overwritten.
-+  */
-+  while( nReserve-- > p->iSize ) assert( pU8[nReserve]==0x65 );
-+  return p;
-+}
- 
- /*
--** Each recursive mutex is an instance of the following structure.
-+** Return the number of bytes currently allocated at address p.
- */
--struct sqlite3_mutex {
--  CRITICAL_SECTION mutex;    /* Mutex controlling the lock */
--  int id;                    /* Mutex type */
--#ifdef SQLITE_DEBUG
--  volatile int nRef;         /* Number of enterances */
--  volatile DWORD owner;      /* Thread holding this mutex */
--  int trace;                 /* True to trace changes */
--#endif
--};
--#define SQLITE_W32_MUTEX_INITIALIZER { 0 }
--#ifdef SQLITE_DEBUG
--#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, 0L, (DWORD)0, 0 }
--#else
--#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 }
--#endif
-+static int sqlite3MemSize(void *p){
-+  struct MemBlockHdr *pHdr;
-+  if( !p ){
-+    return 0;
-+  }
-+  pHdr = sqlite3MemsysGetHeader(p);
-+  return pHdr->iSize;
-+}
- 
- /*
--** 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 win 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.
--**
--** mutexIsNT() is only used for the TryEnterCriticalSection() API call,
--** which is only available if your application was compiled with 
--** _WIN32_WINNT defined to a value >= 0x0400.  Currently, the only
--** call to TryEnterCriticalSection() is #ifdef'ed out, so #ifdef 
--** this out as well.
-+** Initialize the memory allocation subsystem.
- */
--#if 0
--#if SQLITE_OS_WINCE || SQLITE_OS_WINRT
--# define mutexIsNT()  (1)
--#else
--  static int mutexIsNT(void){
--    static int osType = 0;
--    if( osType==0 ){
--      OSVERSIONINFO sInfo;
--      sInfo.dwOSVersionInfoSize = sizeof(sInfo);
--      GetVersionEx(&sInfo);
--      osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
--    }
--    return osType==2;
-+static int sqlite3MemInit(void *NotUsed){
-+  UNUSED_PARAMETER(NotUsed);
-+  assert( (sizeof(struct MemBlockHdr)&7) == 0 );
-+  if( !sqlite3GlobalConfig.bMemstat ){
-+    /* If memory status is enabled, then the malloc.c wrapper will already
-+    ** hold the STATIC_MEM mutex when the routines here are invoked. */
-+    mem.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
-   }
--#endif /* SQLITE_OS_WINCE */
--#endif
-+  return SQLITE_OK;
-+}
- 
--#ifdef SQLITE_DEBUG
- /*
--** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
--** intended for use only inside assert() statements.
-+** Deinitialize the memory allocation subsystem.
- */
--static int winMutexHeld(sqlite3_mutex *p){
--  return p->nRef!=0 && p->owner==GetCurrentThreadId();
--}
--static int winMutexNotheld2(sqlite3_mutex *p, DWORD tid){
--  return p->nRef==0 || p->owner!=tid;
--}
--static int winMutexNotheld(sqlite3_mutex *p){
--  DWORD tid = GetCurrentThreadId(); 
--  return winMutexNotheld2(p, tid);
-+static void sqlite3MemShutdown(void *NotUsed){
-+  UNUSED_PARAMETER(NotUsed);
-+  mem.mutex = 0;
- }
--#endif
--
- 
- /*
--** Initialize and deinitialize the mutex subsystem.
--*/
--static sqlite3_mutex winMutex_staticMutexes[6] = {
--  SQLITE3_MUTEX_INITIALIZER,
--  SQLITE3_MUTEX_INITIALIZER,
--  SQLITE3_MUTEX_INITIALIZER,
--  SQLITE3_MUTEX_INITIALIZER,
--  SQLITE3_MUTEX_INITIALIZER,
--  SQLITE3_MUTEX_INITIALIZER
--};
--static int winMutex_isInit = 0;
--/* As winMutexInit() and winMutexEnd() are called as part
--** of the sqlite3_initialize and sqlite3_shutdown()
--** processing, the "interlocked" magic is probably not
--** strictly necessary.
-+** Round up a request size to the next valid allocation size.
- */
--static long winMutex_lock = 0;
-+static int sqlite3MemRoundup(int n){
-+  return ROUND8(n);
-+}
- 
--SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
-+/*
-+** Fill a buffer with pseudo-random bytes.  This is used to preset
-+** the content of a new memory allocation to unpredictable values and
-+** to clear the content of a freed allocation to unpredictable values.
-+*/
-+static void randomFill(char *pBuf, int nByte){
-+  unsigned int x, y, r;
-+  x = SQLITE_PTR_TO_INT(pBuf);
-+  y = nByte | 1;
-+  while( nByte >= 4 ){
-+    x = (x>>1) ^ (-(x&1) & 0xd0000001);
-+    y = y*1103515245 + 12345;
-+    r = x ^ y;
-+    *(int*)pBuf = r;
-+    pBuf += 4;
-+    nByte -= 4;
-+  }
-+  while( nByte-- > 0 ){
-+    x = (x>>1) ^ (-(x&1) & 0xd0000001);
-+    y = y*1103515245 + 12345;
-+    r = x ^ y;
-+    *(pBuf++) = r & 0xff;
-+  }
-+}
- 
--static int winMutexInit(void){ 
--  /* The first to increment to 1 does actual initialization */
--  if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){
--    int i;
--    for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
--#if SQLITE_OS_WINRT
--      InitializeCriticalSectionEx(&winMutex_staticMutexes[i].mutex, 0, 0);
--#else
--      InitializeCriticalSection(&winMutex_staticMutexes[i].mutex);
--#endif
-+/*
-+** Allocate nByte bytes of memory.
-+*/
-+static void *sqlite3MemMalloc(int nByte){
-+  struct MemBlockHdr *pHdr;
-+  void **pBt;
-+  char *z;
-+  int *pInt;
-+  void *p = 0;
-+  int totalSize;
-+  int nReserve;
-+  sqlite3_mutex_enter(mem.mutex);
-+  assert( mem.disallow==0 );
-+  nReserve = ROUND8(nByte);
-+  totalSize = nReserve + sizeof(*pHdr) + sizeof(int) +
-+               mem.nBacktrace*sizeof(void*) + mem.nTitle;
-+  p = malloc(totalSize);
-+  if( p ){
-+    z = p;
-+    pBt = (void**)&z[mem.nTitle];
-+    pHdr = (struct MemBlockHdr*)&pBt[mem.nBacktrace];
-+    pHdr->pNext = 0;
-+    pHdr->pPrev = mem.pLast;
-+    if( mem.pLast ){
-+      mem.pLast->pNext = pHdr;
-+    }else{
-+      mem.pFirst = pHdr;
-     }
--    winMutex_isInit = 1;
--  }else{
--    /* Someone else is in the process of initing the static mutexes */
--    while( !winMutex_isInit ){
--      sqlite3_win32_sleep(1);
-+    mem.pLast = pHdr;
-+    pHdr->iForeGuard = FOREGUARD;
-+    pHdr->eType = MEMTYPE_HEAP;
-+    pHdr->nBacktraceSlots = mem.nBacktrace;
-+    pHdr->nTitle = mem.nTitle;
-+    if( mem.nBacktrace ){
-+      void *aAddr[40];
-+      pHdr->nBacktrace = backtrace(aAddr, mem.nBacktrace+1)-1;
-+      memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*));
-+      assert(pBt[0]);
-+      if( mem.xBacktrace ){
-+        mem.xBacktrace(nByte, pHdr->nBacktrace-1, &aAddr[1]);
-+      }
-+    }else{
-+      pHdr->nBacktrace = 0;
-+    }
-+    if( mem.nTitle ){
-+      memcpy(z, mem.zTitle, mem.nTitle);
-     }
-+    pHdr->iSize = nByte;
-+    adjustStats(nByte, +1);
-+    pInt = (int*)&pHdr[1];
-+    pInt[nReserve/sizeof(int)] = REARGUARD;
-+    randomFill((char*)pInt, nByte);
-+    memset(((char*)pInt)+nByte, 0x65, nReserve-nByte);
-+    p = (void*)pInt;
-   }
--  return SQLITE_OK; 
-+  sqlite3_mutex_leave(mem.mutex);
-+  return p; 
- }
- 
--static int winMutexEnd(void){ 
--  /* The first to decrement to 0 does actual shutdown 
--  ** (which should be the last to shutdown.) */
--  if( InterlockedCompareExchange(&winMutex_lock, 0, 1)==1 ){
--    if( winMutex_isInit==1 ){
--      int i;
--      for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
--        DeleteCriticalSection(&winMutex_staticMutexes[i].mutex);
--      }
--      winMutex_isInit = 0;
-+/*
-+** Free memory.
-+*/
-+static void sqlite3MemFree(void *pPrior){
-+  struct MemBlockHdr *pHdr;
-+  void **pBt;
-+  char *z;
-+  assert( sqlite3GlobalConfig.bMemstat || sqlite3GlobalConfig.bCoreMutex==0 
-+       || mem.mutex!=0 );
-+  pHdr = sqlite3MemsysGetHeader(pPrior);
-+  pBt = (void**)pHdr;
-+  pBt -= pHdr->nBacktraceSlots;
-+  sqlite3_mutex_enter(mem.mutex);
-+  if( pHdr->pPrev ){
-+    assert( pHdr->pPrev->pNext==pHdr );
-+    pHdr->pPrev->pNext = pHdr->pNext;
-+  }else{
-+    assert( mem.pFirst==pHdr );
-+    mem.pFirst = pHdr->pNext;
-+  }
-+  if( pHdr->pNext ){
-+    assert( pHdr->pNext->pPrev==pHdr );
-+    pHdr->pNext->pPrev = pHdr->pPrev;
-+  }else{
-+    assert( mem.pLast==pHdr );
-+    mem.pLast = pHdr->pPrev;
-+  }
-+  z = (char*)pBt;
-+  z -= pHdr->nTitle;
-+  adjustStats(pHdr->iSize, -1);
-+  randomFill(z, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) +
-+                pHdr->iSize + sizeof(int) + pHdr->nTitle);
-+  free(z);
-+  sqlite3_mutex_leave(mem.mutex);  
-+}
-+
-+/*
-+** Change the size of an existing memory allocation.
-+**
-+** For this debugging implementation, we *always* make a copy of the
-+** allocation into a new place in memory.  In this way, if the 
-+** higher level code is using pointer to the old allocation, it is 
-+** much more likely to break and we are much more liking to find
-+** the error.
-+*/
-+static void *sqlite3MemRealloc(void *pPrior, int nByte){
-+  struct MemBlockHdr *pOldHdr;
-+  void *pNew;
-+  assert( mem.disallow==0 );
-+  assert( (nByte & 7)==0 );     /* EV: R-46199-30249 */
-+  pOldHdr = sqlite3MemsysGetHeader(pPrior);
-+  pNew = sqlite3MemMalloc(nByte);
-+  if( pNew ){
-+    memcpy(pNew, pPrior, nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize);
-+    if( nByte>pOldHdr->iSize ){
-+      randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - pOldHdr->iSize);
-     }
-+    sqlite3MemFree(pPrior);
-   }
--  return SQLITE_OK; 
-+  return pNew;
- }
- 
- /*
--** 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:
-+** Populate the low-level memory allocation function pointers in
-+** sqlite3GlobalConfig.m with pointers to the routines in this file.
-+*/
-+SQLITE_PRIVATE void sqlite3MemSetDefault(void){
-+  static const sqlite3_mem_methods defaultMethods = {
-+     sqlite3MemMalloc,
-+     sqlite3MemFree,
-+     sqlite3MemRealloc,
-+     sqlite3MemSize,
-+     sqlite3MemRoundup,
-+     sqlite3MemInit,
-+     sqlite3MemShutdown,
-+     0
-+  };
-+  sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
-+}
-+
-+/*
-+** Set the "type" of an allocation.
-+*/
-+SQLITE_PRIVATE void sqlite3MemdebugSetType(void *p, u8 eType){
-+  if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
-+    struct MemBlockHdr *pHdr;
-+    pHdr = sqlite3MemsysGetHeader(p);
-+    assert( pHdr->iForeGuard==FOREGUARD );
-+    pHdr->eType = eType;
-+  }
-+}
-+
-+/*
-+** Return TRUE if the mask of type in eType matches the type of the
-+** allocation p.  Also return true if p==NULL.
- **
--** <ul>
--** <li>  SQLITE_MUTEX_FAST
--** <li>  SQLITE_MUTEX_RECURSIVE
--** <li>  SQLITE_MUTEX_STATIC_MASTER
--** <li>  SQLITE_MUTEX_STATIC_MEM
--** <li>  SQLITE_MUTEX_STATIC_MEM2
--** <li>  SQLITE_MUTEX_STATIC_PRNG
--** <li>  SQLITE_MUTEX_STATIC_LRU
--** <li>  SQLITE_MUTEX_STATIC_PMEM
--** </ul>
-+** This routine is designed for use within an assert() statement, to
-+** verify the type of an allocation.  For example:
- **
--** The first two constants cause sqlite3_mutex_alloc() to create
--** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
--** 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.  But 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.
-+**     assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
-+*/
-+SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){
-+  int rc = 1;
-+  if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
-+    struct MemBlockHdr *pHdr;
-+    pHdr = sqlite3MemsysGetHeader(p);
-+    assert( pHdr->iForeGuard==FOREGUARD );         /* Allocation is valid */
-+    if( (pHdr->eType&eType)==0 ){
-+      rc = 0;
-+    }
-+  }
-+  return rc;
-+}
-+
-+/*
-+** Return TRUE if the mask of type in eType matches no bits of the type of the
-+** allocation p.  Also return true if p==NULL.
- **
--** The other allowed parameters to sqlite3_mutex_alloc() each return
--** a pointer to a static preexisting mutex.  Six 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
--** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
--** SQLITE_MUTEX_RECURSIVE.
-+** This routine is designed for use within an assert() statement, to
-+** verify the type of an allocation.  For example:
- **
--** 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 
--** mutex types, the same mutex is returned on every call that has
--** the same type number.
-+**     assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
- */
--static sqlite3_mutex *winMutexAlloc(int iType){
--  sqlite3_mutex *p;
--
--  switch( iType ){
--    case SQLITE_MUTEX_FAST:
--    case SQLITE_MUTEX_RECURSIVE: {
--      p = sqlite3MallocZero( sizeof(*p) );
--      if( p ){  
--#ifdef SQLITE_DEBUG
--        p->id = iType;
--#endif
--#if SQLITE_OS_WINRT
--        InitializeCriticalSectionEx(&p->mutex, 0, 0);
--#else
--        InitializeCriticalSection(&p->mutex);
--#endif
--      }
--      break;
--    }
--    default: {
--      assert( winMutex_isInit==1 );
--      assert( iType-2 >= 0 );
--      assert( iType-2 < ArraySize(winMutex_staticMutexes) );
--      p = &winMutex_staticMutexes[iType-2];
--#ifdef SQLITE_DEBUG
--      p->id = iType;
--#endif
--      break;
-+SQLITE_PRIVATE int sqlite3MemdebugNoType(void *p, u8 eType){
-+  int rc = 1;
-+  if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
-+    struct MemBlockHdr *pHdr;
-+    pHdr = sqlite3MemsysGetHeader(p);
-+    assert( pHdr->iForeGuard==FOREGUARD );         /* Allocation is valid */
-+    if( (pHdr->eType&eType)!=0 ){
-+      rc = 0;
-     }
-   }
--  return p;
-+  return rc;
- }
- 
--
- /*
--** This routine deallocates a previously
--** allocated mutex.  SQLite is careful to deallocate every
--** mutex that it allocates.
-+** Set the number of backtrace levels kept for each allocation.
-+** A value of zero turns off backtracing.  The number is always rounded
-+** up to a multiple of 2.
- */
--static void winMutexFree(sqlite3_mutex *p){
--  assert( p );
--  assert( p->nRef==0 && p->owner==0 );
--  assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
--  DeleteCriticalSection(&p->mutex);
--  sqlite3_free(p);
-+SQLITE_PRIVATE void sqlite3MemdebugBacktrace(int depth){
-+  if( depth<0 ){ depth = 0; }
-+  if( depth>20 ){ depth = 20; }
-+  depth = (depth+1)&0xfe;
-+  mem.nBacktrace = depth;
-+}
-+
-+SQLITE_PRIVATE void sqlite3MemdebugBacktraceCallback(void (*xBacktrace)(int, int, void **)){
-+  mem.xBacktrace = xBacktrace;
- }
- 
- /*
--** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
--** to enter a mutex.  If another thread is already within the mutex,
--** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
--** 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,
--** 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.
-+** Set the title string for subsequent allocations.
- */
--static void winMutexEnter(sqlite3_mutex *p){
--#ifdef SQLITE_DEBUG
--  DWORD tid = GetCurrentThreadId(); 
--  assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) );
--#endif
--  EnterCriticalSection(&p->mutex);
--#ifdef SQLITE_DEBUG
--  assert( p->nRef>0 || p->owner==0 );
--  p->owner = tid; 
--  p->nRef++;
--  if( p->trace ){
--    printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
-+SQLITE_PRIVATE void sqlite3MemdebugSettitle(const char *zTitle){
-+  unsigned int n = sqlite3Strlen30(zTitle) + 1;
-+  sqlite3_mutex_enter(mem.mutex);
-+  if( n>=sizeof(mem.zTitle) ) n = sizeof(mem.zTitle)-1;
-+  memcpy(mem.zTitle, zTitle, n);
-+  mem.zTitle[n] = 0;
-+  mem.nTitle = ROUND8(n);
-+  sqlite3_mutex_leave(mem.mutex);
-+}
-+
-+SQLITE_PRIVATE void sqlite3MemdebugSync(){
-+  struct MemBlockHdr *pHdr;
-+  for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){
-+    void **pBt = (void**)pHdr;
-+    pBt -= pHdr->nBacktraceSlots;
-+    mem.xBacktrace(pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]);
-   }
--#endif
- }
--static int winMutexTry(sqlite3_mutex *p){
--#ifndef NDEBUG
--  DWORD tid = GetCurrentThreadId(); 
--#endif
--  int rc = SQLITE_BUSY;
--  assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) );
--  /*
--  ** The sqlite3_mutex_try() routine is very rarely used, and when it
--  ** is used it is merely an optimization.  So it is OK for it to always
--  ** fail.  
--  **
--  ** The TryEnterCriticalSection() interface is only available on WinNT.
--  ** And some windows compilers complain if you try to use it without
--  ** first doing some #defines that prevent SQLite from building on Win98.
--  ** For that reason, we will omit this optimization for now.  See
--  ** ticket #2685.
--  */
--#if 0
--  if( mutexIsNT() && TryEnterCriticalSection(&p->mutex) ){
--    p->owner = tid;
--    p->nRef++;
--    rc = SQLITE_OK;
-+
-+/*
-+** Open the file indicated and write a log of all unfreed memory 
-+** allocations into that log.
-+*/
-+SQLITE_PRIVATE void sqlite3MemdebugDump(const char *zFilename){
-+  FILE *out;
-+  struct MemBlockHdr *pHdr;
-+  void **pBt;
-+  int i;
-+  out = fopen(zFilename, "w");
-+  if( out==0 ){
-+    fprintf(stderr, "** Unable to output memory debug output log: %s **\n",
-+                    zFilename);
-+    return;
-   }
--#else
--  UNUSED_PARAMETER(p);
--#endif
--#ifdef SQLITE_DEBUG
--  if( rc==SQLITE_OK && p->trace ){
--    printf("try mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
-+  for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){
-+    char *z = (char*)pHdr;
-+    z -= pHdr->nBacktraceSlots*sizeof(void*) + pHdr->nTitle;
-+    fprintf(out, "**** %lld bytes at %p from %s ****\n", 
-+            pHdr->iSize, &pHdr[1], pHdr->nTitle ? z : "???");
-+    if( pHdr->nBacktrace ){
-+      fflush(out);
-+      pBt = (void**)pHdr;
-+      pBt -= pHdr->nBacktraceSlots;
-+      backtrace_symbols_fd(pBt, pHdr->nBacktrace, fileno(out));
-+      fprintf(out, "\n");
-+    }
-   }
--#endif
--  return rc;
-+  fprintf(out, "COUNTS:\n");
-+  for(i=0; i<NCSIZE-1; i++){
-+    if( mem.nAlloc[i] ){
-+      fprintf(out, "   %5d: %10d %10d %10d\n", 
-+            i*8, mem.nAlloc[i], mem.nCurrent[i], mem.mxCurrent[i]);
-+    }
-+  }
-+  if( mem.nAlloc[NCSIZE-1] ){
-+    fprintf(out, "   %5d: %10d %10d %10d\n",
-+             NCSIZE*8-8, mem.nAlloc[NCSIZE-1],
-+             mem.nCurrent[NCSIZE-1], mem.mxCurrent[NCSIZE-1]);
-+  }
-+  fclose(out);
- }
- 
- /*
--** The sqlite3_mutex_leave() routine exits a mutex that was
--** previously entered by the same thread.  The behavior
--** is undefined if the mutex is not currently entered or
--** is not currently allocated.  SQLite will never do either.
-+** Return the number of times sqlite3MemMalloc() has been called.
- */
--static void winMutexLeave(sqlite3_mutex *p){
--#ifndef NDEBUG
--  DWORD tid = GetCurrentThreadId();
--  assert( p->nRef>0 );
--  assert( p->owner==tid );
--  p->nRef--;
--  if( p->nRef==0 ) p->owner = 0;
--  assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
--#endif
--  LeaveCriticalSection(&p->mutex);
--#ifdef SQLITE_DEBUG
--  if( p->trace ){
--    printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
-+SQLITE_PRIVATE int sqlite3MemdebugMallocCount(){
-+  int i;
-+  int nTotal = 0;
-+  for(i=0; i<NCSIZE; i++){
-+    nTotal += mem.nAlloc[i];
-   }
--#endif
-+  return nTotal;
- }
- 
--SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
--  static const sqlite3_mutex_methods sMutex = {
--    winMutexInit,
--    winMutexEnd,
--    winMutexAlloc,
--    winMutexFree,
--    winMutexEnter,
--    winMutexTry,
--    winMutexLeave,
--#ifdef SQLITE_DEBUG
--    winMutexHeld,
--    winMutexNotheld
--#else
--    0,
--    0
--#endif
--  };
- 
--  return &sMutex;
--}
--#endif /* SQLITE_MUTEX_W32 */
-+#endif /* SQLITE_MEMDEBUG */
- 
--/************** End of mutex_w32.c *******************************************/
--/************** Begin file malloc.c ******************************************/
-+/************** End of mem2.c ************************************************/
-+/************** Begin file mem3.c ********************************************/
- /*
--** 2001 September 15
-+** 2007 October 14
- **
- ** The author disclaims copyright to this source code.  In place of
- ** a legal notice, here is a blessing:
-@@ -18775,1904 +19478,1632 @@
- **    May you share freely, never taking more than you give.
- **
- *************************************************************************
-+** This file contains the C functions that implement a memory
-+** allocation subsystem for use by SQLite. 
- **
--** Memory allocation functions used throughout sqlite.
-+** This version of the memory allocation subsystem omits all
-+** use of malloc(). The SQLite user supplies a block of memory
-+** before calling sqlite3_initialize() from which allocations
-+** are made and returned by the xMalloc() and xRealloc() 
-+** implementations. Once sqlite3_initialize() has been called,
-+** the amount of memory available to SQLite is fixed and cannot
-+** be changed.
-+**
-+** This version of the memory allocation subsystem is included
-+** in the build only if SQLITE_ENABLE_MEMSYS3 is defined.
- */
--/* #include <stdarg.h> */
- 
- /*
--** Attempt to release up to n bytes of non-essential memory currently
--** held by SQLite. An example of non-essential memory is memory used to
--** cache database pages that are not currently in use.
-+** This version of the memory allocator is only built into the library
-+** SQLITE_ENABLE_MEMSYS3 is defined. Defining this symbol does not
-+** mean that the library will use a memory-pool by default, just that
-+** it is available. The mempool allocator is activated by calling
-+** sqlite3_config().
- */
--SQLITE_API int sqlite3_release_memory(int n){
--#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
--  return sqlite3PcacheReleaseMemory(n);
--#else
--  /* IMPLEMENTATION-OF: R-34391-24921 The sqlite3_release_memory() routine
--  ** is a no-op returning zero if SQLite is not compiled with
--  ** SQLITE_ENABLE_MEMORY_MANAGEMENT. */
--  UNUSED_PARAMETER(n);
--  return 0;
--#endif
--}
-+#ifdef SQLITE_ENABLE_MEMSYS3
- 
- /*
--** An instance of the following object records the location of
--** each unused scratch buffer.
-+** Maximum size (in Mem3Blocks) of a "small" chunk.
- */
--typedef struct ScratchFreeslot {
--  struct ScratchFreeslot *pNext;   /* Next unused scratch buffer */
--} ScratchFreeslot;
-+#define MX_SMALL 10
-+
- 
- /*
--** State information local to the memory allocation subsystem.
-+** Number of freelist hash slots
- */
--static SQLITE_WSD struct Mem0Global {
--  sqlite3_mutex *mutex;         /* Mutex to serialize access */
-+#define N_HASH  61
-+
-+/*
-+** A memory allocation (also called a "chunk") consists of two or 
-+** more blocks where each block is 8 bytes.  The first 8 bytes are 
-+** a header that is not returned to the user.
-+**
-+** A chunk is two or more blocks that is either checked out or
-+** free.  The first block has format u.hdr.  u.hdr.size4x is 4 times the
-+** size of the allocation in blocks if the allocation is free.
-+** The u.hdr.size4x&1 bit is true if the chunk is checked out and
-+** false if the chunk is on the freelist.  The u.hdr.size4x&2 bit
-+** is true if the previous chunk is checked out and false if the
-+** previous chunk is free.  The u.hdr.prevSize field is the size of
-+** the previous chunk in blocks if the previous chunk is on the
-+** freelist. If the previous chunk is checked out, then
-+** u.hdr.prevSize can be part of the data for that chunk and should
-+** not be read or written.
-+**
-+** We often identify a chunk by its index in mem3.aPool[].  When
-+** this is done, the chunk index refers to the second block of
-+** the chunk.  In this way, the first chunk has an index of 1.
-+** A chunk index of 0 means "no such chunk" and is the equivalent
-+** of a NULL pointer.
-+**
-+** The second block of free chunks is of the form u.list.  The
-+** two fields form a double-linked list of chunks of related sizes.
-+** Pointers to the head of the list are stored in mem3.aiSmall[] 
-+** for smaller chunks and mem3.aiHash[] for larger chunks.
-+**
-+** The second block of a chunk is user data if the chunk is checked 
-+** out.  If a chunk is checked out, the user data may extend into
-+** the u.hdr.prevSize value of the following chunk.
-+*/
-+typedef struct Mem3Block Mem3Block;
-+struct Mem3Block {
-+  union {
-+    struct {
-+      u32 prevSize;   /* Size of previous chunk in Mem3Block elements */
-+      u32 size4x;     /* 4x the size of current chunk in Mem3Block elements */
-+    } hdr;
-+    struct {
-+      u32 next;       /* Index in mem3.aPool[] of next free chunk */
-+      u32 prev;       /* Index in mem3.aPool[] of previous free chunk */
-+    } list;
-+  } u;
-+};
- 
-+/*
-+** All of the static variables used by this module are collected
-+** into a single structure named "mem3".  This is to keep the
-+** static variables organized and to reduce namespace pollution
-+** when this module is combined with other in the amalgamation.
-+*/
-+static SQLITE_WSD struct Mem3Global {
-   /*
--  ** The alarm callback and its arguments.  The mem0.mutex lock will
--  ** be held while the callback is running.  Recursive calls into
--  ** the memory subsystem are allowed, but no new callbacks will be
--  ** issued.
-+  ** Memory available for allocation. nPool is the size of the array
-+  ** (in Mem3Blocks) pointed to by aPool less 2.
-   */
--  sqlite3_int64 alarmThreshold;
--  void (*alarmCallback)(void*, sqlite3_int64,int);
--  void *alarmArg;
-+  u32 nPool;
-+  Mem3Block *aPool;
- 
-   /*
--  ** Pointers to the end of sqlite3GlobalConfig.pScratch memory
--  ** (so that a range test can be used to determine if an allocation
--  ** being freed came from pScratch) and a pointer to the list of
--  ** unused scratch allocations.
-+  ** True if we are evaluating an out-of-memory callback.
-   */
--  void *pScratchEnd;
--  ScratchFreeslot *pScratchFree;
--  u32 nScratchFree;
-+  int alarmBusy;
-+  
-+  /*
-+  ** Mutex to control access to the memory allocation subsystem.
-+  */
-+  sqlite3_mutex *mutex;
-+  
-+  /*
-+  ** The minimum amount of free space that we have seen.
-+  */
-+  u32 mnMaster;
- 
-   /*
--  ** True if heap is nearly "full" where "full" is defined by the
--  ** sqlite3_soft_heap_limit() setting.
-+  ** iMaster is the index of the master chunk.  Most new allocations
-+  ** occur off of this chunk.  szMaster is the size (in Mem3Blocks)
-+  ** of the current master.  iMaster is 0 if there is not master chunk.
-+  ** The master chunk is not in either the aiHash[] or aiSmall[].
-   */
--  int nearlyFull;
--} mem0 = { 0, 0, 0, 0, 0, 0, 0, 0 };
-+  u32 iMaster;
-+  u32 szMaster;
- 
--#define mem0 GLOBAL(struct Mem0Global, mem0)
-+  /*
-+  ** Array of lists of free blocks according to the block size 
-+  ** for smaller chunks, or a hash on the block size for larger
-+  ** chunks.
-+  */
-+  u32 aiSmall[MX_SMALL-1];   /* For sizes 2 through MX_SMALL, inclusive */
-+  u32 aiHash[N_HASH];        /* For sizes MX_SMALL+1 and larger */
-+} mem3 = { 97535575 };
- 
--/*
--** This routine runs when the memory allocator sees that the
--** total memory allocation is about to exceed the soft heap
--** limit.
--*/
--static void softHeapLimitEnforcer(
--  void *NotUsed, 
--  sqlite3_int64 NotUsed2,
--  int allocSize
--){
--  UNUSED_PARAMETER2(NotUsed, NotUsed2);
--  sqlite3_release_memory(allocSize);
--}
-+#define mem3 GLOBAL(struct Mem3Global, mem3)
- 
- /*
--** Change the alarm callback
-+** Unlink the chunk at mem3.aPool[i] from list it is currently
-+** on.  *pRoot is the list that i is a member of.
- */
--static int sqlite3MemoryAlarm(
--  void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
--  void *pArg,
--  sqlite3_int64 iThreshold
--){
--  int nUsed;
--  sqlite3_mutex_enter(mem0.mutex);
--  mem0.alarmCallback = xCallback;
--  mem0.alarmArg = pArg;
--  mem0.alarmThreshold = iThreshold;
--  nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
--  mem0.nearlyFull = (iThreshold>0 && iThreshold<=nUsed);
--  sqlite3_mutex_leave(mem0.mutex);
--  return SQLITE_OK;
-+static void memsys3UnlinkFromList(u32 i, u32 *pRoot){
-+  u32 next = mem3.aPool[i].u.list.next;
-+  u32 prev = mem3.aPool[i].u.list.prev;
-+  assert( sqlite3_mutex_held(mem3.mutex) );
-+  if( prev==0 ){
-+    *pRoot = next;
-+  }else{
-+    mem3.aPool[prev].u.list.next = next;
-+  }
-+  if( next ){
-+    mem3.aPool[next].u.list.prev = prev;
-+  }
-+  mem3.aPool[i].u.list.next = 0;
-+  mem3.aPool[i].u.list.prev = 0;
- }
- 
--#ifndef SQLITE_OMIT_DEPRECATED
- /*
--** Deprecated external interface.  Internal/core SQLite code
--** should call sqlite3MemoryAlarm.
-+** Unlink the chunk at index i from 
-+** whatever list is currently a member of.
- */
--SQLITE_API int sqlite3_memory_alarm(
--  void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
--  void *pArg,
--  sqlite3_int64 iThreshold
--){
--  return sqlite3MemoryAlarm(xCallback, pArg, iThreshold);
-+static void memsys3Unlink(u32 i){
-+  u32 size, hash;
-+  assert( sqlite3_mutex_held(mem3.mutex) );
-+  assert( (mem3.aPool[i-1].u.hdr.size4x & 1)==0 );
-+  assert( i>=1 );
-+  size = mem3.aPool[i-1].u.hdr.size4x/4;
-+  assert( size==mem3.aPool[i+size-1].u.hdr.prevSize );
-+  assert( size>=2 );
-+  if( size <= MX_SMALL ){
-+    memsys3UnlinkFromList(i, &mem3.aiSmall[size-2]);
-+  }else{
-+    hash = size % N_HASH;
-+    memsys3UnlinkFromList(i, &mem3.aiHash[hash]);
-+  }
- }
--#endif
- 
- /*
--** Set the soft heap-size limit for the library. Passing a zero or 
--** negative value indicates no limit.
-+** Link the chunk at mem3.aPool[i] so that is on the list rooted
-+** at *pRoot.
- */
--SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){
--  sqlite3_int64 priorLimit;
--  sqlite3_int64 excess;
--#ifndef SQLITE_OMIT_AUTOINIT
--  int rc = sqlite3_initialize();
--  if( rc ) return -1;
--#endif
--  sqlite3_mutex_enter(mem0.mutex);
--  priorLimit = mem0.alarmThreshold;
--  sqlite3_mutex_leave(mem0.mutex);
--  if( n<0 ) return priorLimit;
--  if( n>0 ){
--    sqlite3MemoryAlarm(softHeapLimitEnforcer, 0, n);
--  }else{
--    sqlite3MemoryAlarm(0, 0, 0);
-+static void memsys3LinkIntoList(u32 i, u32 *pRoot){
-+  assert( sqlite3_mutex_held(mem3.mutex) );
-+  mem3.aPool[i].u.list.next = *pRoot;
-+  mem3.aPool[i].u.list.prev = 0;
-+  if( *pRoot ){
-+    mem3.aPool[*pRoot].u.list.prev = i;
-   }
--  excess = sqlite3_memory_used() - n;
--  if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff));
--  return priorLimit;
--}
--SQLITE_API void sqlite3_soft_heap_limit(int n){
--  if( n<0 ) n = 0;
--  sqlite3_soft_heap_limit64(n);
-+  *pRoot = i;
- }
- 
- /*
--** Initialize the memory allocation subsystem.
-+** Link the chunk at index i into either the appropriate
-+** small chunk list, or into the large chunk hash table.
- */
--SQLITE_PRIVATE int sqlite3MallocInit(void){
--  if( sqlite3GlobalConfig.m.xMalloc==0 ){
--    sqlite3MemSetDefault();
--  }
--  memset(&mem0, 0, sizeof(mem0));
--  if( sqlite3GlobalConfig.bCoreMutex ){
--    mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
--  }
--  if( sqlite3GlobalConfig.pScratch && sqlite3GlobalConfig.szScratch>=100
--      && sqlite3GlobalConfig.nScratch>0 ){
--    int i, n, sz;
--    ScratchFreeslot *pSlot;
--    sz = ROUNDDOWN8(sqlite3GlobalConfig.szScratch);
--    sqlite3GlobalConfig.szScratch = sz;
--    pSlot = (ScratchFreeslot*)sqlite3GlobalConfig.pScratch;
--    n = sqlite3GlobalConfig.nScratch;
--    mem0.pScratchFree = pSlot;
--    mem0.nScratchFree = n;
--    for(i=0; i<n-1; i++){
--      pSlot->pNext = (ScratchFreeslot*)(sz+(char*)pSlot);
--      pSlot = pSlot->pNext;
--    }
--    pSlot->pNext = 0;
--    mem0.pScratchEnd = (void*)&pSlot[1];
-+static void memsys3Link(u32 i){
-+  u32 size, hash;
-+  assert( sqlite3_mutex_held(mem3.mutex) );
-+  assert( i>=1 );
-+  assert( (mem3.aPool[i-1].u.hdr.size4x & 1)==0 );
-+  size = mem3.aPool[i-1].u.hdr.size4x/4;
-+  assert( size==mem3.aPool[i+size-1].u.hdr.prevSize );
-+  assert( size>=2 );
-+  if( size <= MX_SMALL ){
-+    memsys3LinkIntoList(i, &mem3.aiSmall[size-2]);
-   }else{
--    mem0.pScratchEnd = 0;
--    sqlite3GlobalConfig.pScratch = 0;
--    sqlite3GlobalConfig.szScratch = 0;
--    sqlite3GlobalConfig.nScratch = 0;
--  }
--  if( sqlite3GlobalConfig.pPage==0 || sqlite3GlobalConfig.szPage<512
--      || sqlite3GlobalConfig.nPage<1 ){
--    sqlite3GlobalConfig.pPage = 0;
--    sqlite3GlobalConfig.szPage = 0;
--    sqlite3GlobalConfig.nPage = 0;
-+    hash = size % N_HASH;
-+    memsys3LinkIntoList(i, &mem3.aiHash[hash]);
-   }
--  return sqlite3GlobalConfig.m.xInit(sqlite3GlobalConfig.m.pAppData);
- }
- 
- /*
--** Return true if the heap is currently under memory pressure - in other
--** words if the amount of heap used is close to the limit set by
--** sqlite3_soft_heap_limit().
-+** If the STATIC_MEM mutex is not already held, obtain it now. The mutex
-+** will already be held (obtained by code in malloc.c) if
-+** sqlite3GlobalConfig.bMemStat is true.
- */
--SQLITE_PRIVATE int sqlite3HeapNearlyFull(void){
--  return mem0.nearlyFull;
-+static void memsys3Enter(void){
-+  if( sqlite3GlobalConfig.bMemstat==0 && mem3.mutex==0 ){
-+    mem3.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
-+  }
-+  sqlite3_mutex_enter(mem3.mutex);
-+}
-+static void memsys3Leave(void){
-+  sqlite3_mutex_leave(mem3.mutex);
- }
- 
- /*
--** Deinitialize the memory allocation subsystem.
-+** Called when we are unable to satisfy an allocation of nBytes.
- */
--SQLITE_PRIVATE void sqlite3MallocEnd(void){
--  if( sqlite3GlobalConfig.m.xShutdown ){
--    sqlite3GlobalConfig.m.xShutdown(sqlite3GlobalConfig.m.pAppData);
-+static void memsys3OutOfMemory(int nByte){
-+  if( !mem3.alarmBusy ){
-+    mem3.alarmBusy = 1;
-+    assert( sqlite3_mutex_held(mem3.mutex) );
-+    sqlite3_mutex_leave(mem3.mutex);
-+    sqlite3_release_memory(nByte);
-+    sqlite3_mutex_enter(mem3.mutex);
-+    mem3.alarmBusy = 0;
-   }
--  memset(&mem0, 0, sizeof(mem0));
- }
- 
--/*
--** Return the amount of memory currently checked out.
--*/
--SQLITE_API sqlite3_int64 sqlite3_memory_used(void){
--  int n, mx;
--  sqlite3_int64 res;
--  sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, 0);
--  res = (sqlite3_int64)n;  /* Work around bug in Borland C. Ticket #3216 */
--  return res;
--}
- 
- /*
--** Return the maximum amount of memory that has ever been
--** checked out since either the beginning of this process
--** or since the most recent reset.
-+** Chunk i is a free chunk that has been unlinked.  Adjust its 
-+** size parameters for check-out and return a pointer to the 
-+** user portion of the chunk.
- */
--SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
--  int n, mx;
--  sqlite3_int64 res;
--  sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, resetFlag);
--  res = (sqlite3_int64)mx;  /* Work around bug in Borland C. Ticket #3216 */
--  return res;
-+static void *memsys3Checkout(u32 i, u32 nBlock){
-+  u32 x;
-+  assert( sqlite3_mutex_held(mem3.mutex) );
-+  assert( i>=1 );
-+  assert( mem3.aPool[i-1].u.hdr.size4x/4==nBlock );
-+  assert( mem3.aPool[i+nBlock-1].u.hdr.prevSize==nBlock );
-+  x = mem3.aPool[i-1].u.hdr.size4x;
-+  mem3.aPool[i-1].u.hdr.size4x = nBlock*4 | 1 | (x&2);
-+  mem3.aPool[i+nBlock-1].u.hdr.prevSize = nBlock;
-+  mem3.aPool[i+nBlock-1].u.hdr.size4x |= 2;
-+  return &mem3.aPool[i];
- }
- 
- /*
--** Trigger the alarm 
-+** Carve a piece off of the end of the mem3.iMaster free chunk.
-+** Return a pointer to the new allocation.  Or, if the master chunk
-+** is not large enough, return 0.
- */
--static void sqlite3MallocAlarm(int nByte){
--  void (*xCallback)(void*,sqlite3_int64,int);
--  sqlite3_int64 nowUsed;
--  void *pArg;
--  if( mem0.alarmCallback==0 ) return;
--  xCallback = mem0.alarmCallback;
--  nowUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
--  pArg = mem0.alarmArg;
--  mem0.alarmCallback = 0;
--  sqlite3_mutex_leave(mem0.mutex);
--  xCallback(pArg, nowUsed, nByte);
--  sqlite3_mutex_enter(mem0.mutex);
--  mem0.alarmCallback = xCallback;
--  mem0.alarmArg = pArg;
-+static void *memsys3FromMaster(u32 nBlock){
-+  assert( sqlite3_mutex_held(mem3.mutex) );
-+  assert( mem3.szMaster>=nBlock );
-+  if( nBlock>=mem3.szMaster-1 ){
-+    /* Use the entire master */
-+    void *p = memsys3Checkout(mem3.iMaster, mem3.szMaster);
-+    mem3.iMaster = 0;
-+    mem3.szMaster = 0;
-+    mem3.mnMaster = 0;
-+    return p;
-+  }else{
-+    /* Split the master block.  Return the tail. */
-+    u32 newi, x;
-+    newi = mem3.iMaster + mem3.szMaster - nBlock;
-+    assert( newi > mem3.iMaster+1 );
-+    mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = nBlock;
-+    mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x |= 2;
-+    mem3.aPool[newi-1].u.hdr.size4x = nBlock*4 + 1;
-+    mem3.szMaster -= nBlock;
-+    mem3.aPool[newi-1].u.hdr.prevSize = mem3.szMaster;
-+    x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2;
-+    mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x;
-+    if( mem3.szMaster < mem3.mnMaster ){
-+      mem3.mnMaster = mem3.szMaster;
-+    }
-+    return (void*)&mem3.aPool[newi];
-+  }
- }
- 
- /*
--** Do a memory allocation with statistics and alarms.  Assume the
--** lock is already held.
-+** *pRoot is the head of a list of free chunks of the same size
-+** or same size hash.  In other words, *pRoot is an entry in either
-+** mem3.aiSmall[] or mem3.aiHash[].  
-+**
-+** This routine examines all entries on the given list and tries
-+** to coalesce each entries with adjacent free chunks.  
-+**
-+** If it sees a chunk that is larger than mem3.iMaster, it replaces 
-+** the current mem3.iMaster with the new larger chunk.  In order for
-+** this mem3.iMaster replacement to work, the master chunk must be
-+** linked into the hash tables.  That is not the normal state of
-+** affairs, of course.  The calling routine must link the master
-+** chunk before invoking this routine, then must unlink the (possibly
-+** changed) master chunk once this routine has finished.
- */
--static int mallocWithAlarm(int n, void **pp){
--  int nFull;
--  void *p;
--  assert( sqlite3_mutex_held(mem0.mutex) );
--  nFull = sqlite3GlobalConfig.m.xRoundup(n);
--  sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n);
--  if( mem0.alarmCallback!=0 ){
--    int nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
--    if( nUsed >= mem0.alarmThreshold - nFull ){
--      mem0.nearlyFull = 1;
--      sqlite3MallocAlarm(nFull);
-+static void memsys3Merge(u32 *pRoot){
-+  u32 iNext, prev, size, i, x;
-+
-+  assert( sqlite3_mutex_held(mem3.mutex) );
-+  for(i=*pRoot; i>0; i=iNext){
-+    iNext = mem3.aPool[i].u.list.next;
-+    size = mem3.aPool[i-1].u.hdr.size4x;
-+    assert( (size&1)==0 );
-+    if( (size&2)==0 ){
-+      memsys3UnlinkFromList(i, pRoot);
-+      assert( i > mem3.aPool[i-1].u.hdr.prevSize );
-+      prev = i - mem3.aPool[i-1].u.hdr.prevSize;
-+      if( prev==iNext ){
-+        iNext = mem3.aPool[prev].u.list.next;
-+      }
-+      memsys3Unlink(prev);
-+      size = i + size/4 - prev;
-+      x = mem3.aPool[prev-1].u.hdr.size4x & 2;
-+      mem3.aPool[prev-1].u.hdr.size4x = size*4 | x;
-+      mem3.aPool[prev+size-1].u.hdr.prevSize = size;
-+      memsys3Link(prev);
-+      i = prev;
-     }else{
--      mem0.nearlyFull = 0;
-+      size /= 4;
-+    }
-+    if( size>mem3.szMaster ){
-+      mem3.iMaster = i;
-+      mem3.szMaster = size;
-     }
-   }
--  p = sqlite3GlobalConfig.m.xMalloc(nFull);
--#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
--  if( p==0 && mem0.alarmCallback ){
--    sqlite3MallocAlarm(nFull);
--    p = sqlite3GlobalConfig.m.xMalloc(nFull);
--  }
--#endif
--  if( p ){
--    nFull = sqlite3MallocSize(p);
--    sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nFull);
--    sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, 1);
--  }
--  *pp = p;
--  return nFull;
- }
- 
- /*
--** Allocate memory.  This routine is like sqlite3_malloc() except that it
--** assumes the memory subsystem has already been initialized.
-+** Return a block of memory of at least nBytes in size.
-+** Return NULL if unable.
-+**
-+** This function assumes that the necessary mutexes, if any, are
-+** already held by the caller. Hence "Unsafe".
- */
--SQLITE_PRIVATE void *sqlite3Malloc(int n){
--  void *p;
--  if( n<=0               /* IMP: R-65312-04917 */ 
--   || 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
--    ** 255 bytes of overhead.  SQLite itself will never use anything near
--    ** this amount.  The only way to reach the limit is with sqlite3_malloc() */
--    p = 0;
--  }else if( sqlite3GlobalConfig.bMemstat ){
--    sqlite3_mutex_enter(mem0.mutex);
--    mallocWithAlarm(n, &p);
--    sqlite3_mutex_leave(mem0.mutex);
-+static void *memsys3MallocUnsafe(int nByte){
-+  u32 i;
-+  u32 nBlock;
-+  u32 toFree;
-+
-+  assert( sqlite3_mutex_held(mem3.mutex) );
-+  assert( sizeof(Mem3Block)==8 );
-+  if( nByte<=12 ){
-+    nBlock = 2;
-   }else{
--    p = sqlite3GlobalConfig.m.xMalloc(n);
-+    nBlock = (nByte + 11)/8;
-   }
--  assert( EIGHT_BYTE_ALIGNMENT(p) );  /* IMP: R-04675-44850 */
--  return p;
--}
-+  assert( nBlock>=2 );
- 
--/*
--** This version of the memory allocation is for use by the application.
--** First make sure the memory subsystem is initialized, then do the
--** allocation.
--*/
--SQLITE_API void *sqlite3_malloc(int n){
--#ifndef SQLITE_OMIT_AUTOINIT
--  if( sqlite3_initialize() ) return 0;
--#endif
--  return sqlite3Malloc(n);
--}
--
--/*
--** Each thread may only have a single outstanding allocation from
--** xScratchMalloc().  We verify this constraint in the single-threaded
--** case by setting scratchAllocOut to 1 when an allocation
--** is outstanding clearing it when the allocation is freed.
--*/
--#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
--static int scratchAllocOut = 0;
--#endif
-+  /* STEP 1:
-+  ** Look for an entry of the correct size in either the small
-+  ** chunk table or in the large chunk hash table.  This is
-+  ** successful most of the time (about 9 times out of 10).
-+  */
-+  if( nBlock <= MX_SMALL ){
-+    i = mem3.aiSmall[nBlock-2];
-+    if( i>0 ){
-+      memsys3UnlinkFromList(i, &mem3.aiSmall[nBlock-2]);
-+      return memsys3Checkout(i, nBlock);
-+    }
-+  }else{
-+    int hash = nBlock % N_HASH;
-+    for(i=mem3.aiHash[hash]; i>0; i=mem3.aPool[i].u.list.next){
-+      if( mem3.aPool[i-1].u.hdr.size4x/4==nBlock ){
-+        memsys3UnlinkFromList(i, &mem3.aiHash[hash]);
-+        return memsys3Checkout(i, nBlock);
-+      }
-+    }
-+  }
- 
-+  /* STEP 2:
-+  ** Try to satisfy the allocation by carving a piece off of the end
-+  ** of the master chunk.  This step usually works if step 1 fails.
-+  */
-+  if( mem3.szMaster>=nBlock ){
-+    return memsys3FromMaster(nBlock);
-+  }
- 
--/*
--** Allocate memory that is to be used and released right away.
--** This routine is similar to alloca() in that it is not intended
--** for situations where the memory might be held long-term.  This
--** routine is intended to get memory to old large transient data
--** structures that would not normally fit on the stack of an
--** embedded processor.
--*/
--SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){
--  void *p;
--  assert( n>0 );
- 
--  sqlite3_mutex_enter(mem0.mutex);
--  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);
--    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 = sqlite3GlobalConfig.m.xMalloc(n);
-+  /* STEP 3:  
-+  ** Loop through the entire memory pool.  Coalesce adjacent free
-+  ** chunks.  Recompute the master chunk as the largest free chunk.
-+  ** Then try again to satisfy the allocation by carving a piece off
-+  ** of the end of the master chunk.  This step happens very
-+  ** rarely (we hope!)
-+  */
-+  for(toFree=nBlock*16; toFree<(mem3.nPool*16); toFree *= 2){
-+    memsys3OutOfMemory(toFree);
-+    if( mem3.iMaster ){
-+      memsys3Link(mem3.iMaster);
-+      mem3.iMaster = 0;
-+      mem3.szMaster = 0;
-+    }
-+    for(i=0; i<N_HASH; i++){
-+      memsys3Merge(&mem3.aiHash[i]);
-+    }
-+    for(i=0; i<MX_SMALL-1; i++){
-+      memsys3Merge(&mem3.aiSmall[i]);
-+    }
-+    if( mem3.szMaster ){
-+      memsys3Unlink(mem3.iMaster);
-+      if( mem3.szMaster>=nBlock ){
-+        return memsys3FromMaster(nBlock);
-+      }
-     }
--    sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH);
-   }
--  assert( sqlite3_mutex_notheld(mem0.mutex) );
--
--
--#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 );
--  if( p ) scratchAllocOut++;
--#endif
- 
--  return p;
-+  /* If none of the above worked, then we fail. */
-+  return 0;
- }
--SQLITE_PRIVATE void sqlite3ScratchFree(void *p){
--  if( p ){
- 
--#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
--    /* Verify that no more than two scratch allocation per thread
--    ** is 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 && scratchAllocOut<=2 );
--    scratchAllocOut--;
--#endif
-+/*
-+** Free an outstanding memory allocation.
-+**
-+** This function assumes that the necessary mutexes, if any, are
-+** already held by the caller. Hence "Unsafe".
-+*/
-+static void memsys3FreeUnsafe(void *pOld){
-+  Mem3Block *p = (Mem3Block*)pOld;
-+  int i;
-+  u32 size, x;
-+  assert( sqlite3_mutex_held(mem3.mutex) );
-+  assert( p>mem3.aPool && p<&mem3.aPool[mem3.nPool] );
-+  i = p - mem3.aPool;
-+  assert( (mem3.aPool[i-1].u.hdr.size4x&1)==1 );
-+  size = mem3.aPool[i-1].u.hdr.size4x/4;
-+  assert( i+size<=mem3.nPool+1 );
-+  mem3.aPool[i-1].u.hdr.size4x &= ~1;
-+  mem3.aPool[i+size-1].u.hdr.prevSize = size;
-+  mem3.aPool[i+size-1].u.hdr.size4x &= ~2;
-+  memsys3Link(i);
- 
--    if( p>=sqlite3GlobalConfig.pScratch && p<mem0.pScratchEnd ){
--      /* Release memory from the SQLITE_CONFIG_SCRATCH allocation */
--      ScratchFreeslot *pSlot;
--      pSlot = (ScratchFreeslot*)p;
--      sqlite3_mutex_enter(mem0.mutex);
--      pSlot->pNext = mem0.pScratchFree;
--      mem0.pScratchFree = pSlot;
--      mem0.nScratchFree++;
--      assert( mem0.nScratchFree <= (u32)sqlite3GlobalConfig.nScratch );
--      sqlite3StatusAdd(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) );
--      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);
--        sqlite3GlobalConfig.m.xFree(p);
--        sqlite3_mutex_leave(mem0.mutex);
--      }else{
--        sqlite3GlobalConfig.m.xFree(p);
--      }
-+  /* Try to expand the master using the newly freed chunk */
-+  if( mem3.iMaster ){
-+    while( (mem3.aPool[mem3.iMaster-1].u.hdr.size4x&2)==0 ){
-+      size = mem3.aPool[mem3.iMaster-1].u.hdr.prevSize;
-+      mem3.iMaster -= size;
-+      mem3.szMaster += size;
-+      memsys3Unlink(mem3.iMaster);
-+      x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2;
-+      mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x;
-+      mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = mem3.szMaster;
-+    }
-+    x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2;
-+    while( (mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x&1)==0 ){
-+      memsys3Unlink(mem3.iMaster+mem3.szMaster);
-+      mem3.szMaster += mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x/4;
-+      mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x;
-+      mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = mem3.szMaster;
-     }
-   }
- }
- 
- /*
--** TRUE if p is a lookaside memory allocation from db
-+** Return the size of an outstanding allocation, in bytes.  The
-+** size returned omits the 8-byte header overhead.  This only
-+** works for chunks that are currently checked out.
- */
--#ifndef SQLITE_OMIT_LOOKASIDE
--static int isLookaside(sqlite3 *db, void *p){
--  return p && p>=db->lookaside.pStart && p<db->lookaside.pEnd;
-+static int memsys3Size(void *p){
-+  Mem3Block *pBlock;
-+  if( p==0 ) return 0;
-+  pBlock = (Mem3Block*)p;
-+  assert( (pBlock[-1].u.hdr.size4x&1)!=0 );
-+  return (pBlock[-1].u.hdr.size4x&~3)*2 - 4;
- }
--#else
--#define isLookaside(A,B) 0
--#endif
- 
- /*
--** Return the size of a memory allocation previously obtained from
--** sqlite3Malloc() or sqlite3_malloc().
-+** Round up a request size to the next valid allocation size.
- */
--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 || sqlite3_mutex_held(db->mutex) );
--  if( db && isLookaside(db, p) ){
--    return db->lookaside.sz;
-+static int memsys3Roundup(int n){
-+  if( n<=12 ){
-+    return 12;
-   }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);
-+    return ((n+11)&~7) - 4;
-   }
- }
- 
- /*
--** Free memory previously obtained from sqlite3Malloc().
-+** Allocate nBytes of memory.
- */
--SQLITE_API void sqlite3_free(void *p){
--  if( p==0 ) return;  /* IMP: R-49053-54554 */
--  assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
--  assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
--  if( sqlite3GlobalConfig.bMemstat ){
--    sqlite3_mutex_enter(mem0.mutex);
--    sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p));
--    sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1);
--    sqlite3GlobalConfig.m.xFree(p);
--    sqlite3_mutex_leave(mem0.mutex);
--  }else{
--    sqlite3GlobalConfig.m.xFree(p);
--  }
-+static void *memsys3Malloc(int nBytes){
-+  sqlite3_int64 *p;
-+  assert( nBytes>0 );          /* malloc.c filters out 0 byte requests */
-+  memsys3Enter();
-+  p = memsys3MallocUnsafe(nBytes);
-+  memsys3Leave();
-+  return (void*)p; 
- }
- 
- /*
--** Free memory that might be associated with a particular database
--** connection.
-+** Free memory.
- */
--SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
--  assert( db==0 || sqlite3_mutex_held(db->mutex) );
--  if( db ){
--    if( db->pnBytesFreed ){
--      *db->pnBytesFreed += sqlite3DbMallocSize(db, p);
--      return;
--    }
--    if( isLookaside(db, p) ){
--      LookasideSlot *pBuf = (LookasideSlot*)p;
--#if SQLITE_DEBUG
--      /* Trash all content in the buffer being freed */
--      memset(p, 0xaa, db->lookaside.sz);
--#endif
--      pBuf->pNext = db->lookaside.pFree;
--      db->lookaside.pFree = pBuf;
--      db->lookaside.nOut--;
--      return;
--    }
--  }
--  assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
--  assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
--  assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
--  sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
--  sqlite3_free(p);
-+static void memsys3Free(void *pPrior){
-+  assert( pPrior );
-+  memsys3Enter();
-+  memsys3FreeUnsafe(pPrior);
-+  memsys3Leave();
- }
- 
- /*
- ** Change the size of an existing memory allocation
- */
--SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, int nBytes){
--  int nOld, nNew, nDiff;
--  void *pNew;
--  if( pOld==0 ){
--    return sqlite3Malloc(nBytes); /* IMP: R-28354-25769 */
-+static void *memsys3Realloc(void *pPrior, int nBytes){
-+  int nOld;
-+  void *p;
-+  if( pPrior==0 ){
-+    return sqlite3_malloc(nBytes);
-   }
-   if( nBytes<=0 ){
--    sqlite3_free(pOld); /* IMP: R-31593-10574 */
-+    sqlite3_free(pPrior);
-     return 0;
-   }
--  if( nBytes>=0x7fffff00 ){
--    /* The 0x7ffff00 limit term is explained in comments on sqlite3Malloc() */
--    return 0;
-+  nOld = memsys3Size(pPrior);
-+  if( nBytes<=nOld && nBytes>=nOld-128 ){
-+    return pPrior;
-   }
--  nOld = sqlite3MallocSize(pOld);
--  /* 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);
--  if( nOld==nNew ){
--    pNew = pOld;
--  }else if( sqlite3GlobalConfig.bMemstat ){
--    sqlite3_mutex_enter(mem0.mutex);
--    sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, 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);
--      pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
--    }
--    if( pNew ){
--      nNew = sqlite3MallocSize(pNew);
--      sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
-+  memsys3Enter();
-+  p = memsys3MallocUnsafe(nBytes);
-+  if( p ){
-+    if( nOld<nBytes ){
-+      memcpy(p, pPrior, nOld);
-+    }else{
-+      memcpy(p, pPrior, nBytes);
-     }
--    sqlite3_mutex_leave(mem0.mutex);
--  }else{
--    pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
-+    memsys3FreeUnsafe(pPrior);
-   }
--  assert( EIGHT_BYTE_ALIGNMENT(pNew) ); /* IMP: R-04675-44850 */
--  return pNew;
-+  memsys3Leave();
-+  return p;
- }
- 
- /*
--** The public interface to sqlite3Realloc.  Make sure that the memory
--** subsystem is initialized prior to invoking sqliteRealloc.
-+** Initialize this module.
- */
--SQLITE_API void *sqlite3_realloc(void *pOld, int n){
--#ifndef SQLITE_OMIT_AUTOINIT
--  if( sqlite3_initialize() ) return 0;
--#endif
--  return sqlite3Realloc(pOld, n);
--}
-+static int memsys3Init(void *NotUsed){
-+  UNUSED_PARAMETER(NotUsed);
-+  if( !sqlite3GlobalConfig.pHeap ){
-+    return SQLITE_ERROR;
-+  }
- 
-+  /* Store a pointer to the memory block in global structure mem3. */
-+  assert( sizeof(Mem3Block)==8 );
-+  mem3.aPool = (Mem3Block *)sqlite3GlobalConfig.pHeap;
-+  mem3.nPool = (sqlite3GlobalConfig.nHeap / sizeof(Mem3Block)) - 2;
- 
--/*
--** Allocate and zero memory.
--*/ 
--SQLITE_PRIVATE void *sqlite3MallocZero(int n){
--  void *p = sqlite3Malloc(n);
--  if( p ){
--    memset(p, 0, n);
--  }
--  return p;
-+  /* Initialize the master block. */
-+  mem3.szMaster = mem3.nPool;
-+  mem3.mnMaster = mem3.szMaster;
-+  mem3.iMaster = 1;
-+  mem3.aPool[0].u.hdr.size4x = (mem3.szMaster<<2) + 2;
-+  mem3.aPool[mem3.nPool].u.hdr.prevSize = mem3.nPool;
-+  mem3.aPool[mem3.nPool].u.hdr.size4x = 1;
-+
-+  return SQLITE_OK;
- }
- 
- /*
--** Allocate and zero memory.  If the allocation fails, make
--** the mallocFailed flag in the connection pointer.
-+** Deinitialize this module.
- */
--SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3 *db, int n){
--  void *p = sqlite3DbMallocRaw(db, n);
--  if( p ){
--    memset(p, 0, n);
--  }
--  return p;
-+static void memsys3Shutdown(void *NotUsed){
-+  UNUSED_PARAMETER(NotUsed);
-+  mem3.mutex = 0;
-+  return;
- }
- 
-+
-+
- /*
--** Allocate and zero memory.  If the allocation fails, make
--** the mallocFailed flag in the connection pointer.
--**
--** If db!=0 and db->mallocFailed is true (indicating a prior malloc
--** failure on the same database connection) then always return 0.
--** Hence for a particular database connection, once malloc starts
--** failing, it fails consistently until mallocFailed is reset.
--** This is an important assumption.  There are many places in the
--** code that do things like this:
--**
--**         int *a = (int*)sqlite3DbMallocRaw(db, 100);
--**         int *b = (int*)sqlite3DbMallocRaw(db, 200);
--**         if( b ) a[10] = 9;
--**
--** In other words, if a subsequent malloc (ex: "b") worked, it is assumed
--** that all prior mallocs (ex: "a") worked too.
-+** Open the file indicated and write a log of all unfreed memory 
-+** allocations into that log.
- */
--SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3 *db, int n){
--  void *p;
--  assert( db==0 || sqlite3_mutex_held(db->mutex) );
--  assert( db==0 || db->pnBytesFreed==0 );
--#ifndef SQLITE_OMIT_LOOKASIDE
--  if( db ){
--    LookasideSlot *pBuf;
--    if( db->mallocFailed ){
--      return 0;
--    }
--    if( db->lookaside.bEnabled ){
--      if( n>db->lookaside.sz ){
--        db->lookaside.anStat[1]++;
--      }else if( (pBuf = db->lookaside.pFree)==0 ){
--        db->lookaside.anStat[2]++;
--      }else{
--        db->lookaside.pFree = pBuf->pNext;
--        db->lookaside.nOut++;
--        db->lookaside.anStat[0]++;
--        if( db->lookaside.nOut>db->lookaside.mxOut ){
--          db->lookaside.mxOut = db->lookaside.nOut;
--        }
--        return (void*)pBuf;
--      }
-+SQLITE_PRIVATE void sqlite3Memsys3Dump(const char *zFilename){
-+#ifdef SQLITE_DEBUG
-+  FILE *out;
-+  u32 i, j;
-+  u32 size;
-+  if( zFilename==0 || zFilename[0]==0 ){
-+    out = stdout;
-+  }else{
-+    out = fopen(zFilename, "w");
-+    if( out==0 ){
-+      fprintf(stderr, "** Unable to output memory debug output log: %s **\n",
-+                      zFilename);
-+      return;
-     }
-   }
--#else
--  if( db && db->mallocFailed ){
--    return 0;
--  }
--#endif
--  p = sqlite3Malloc(n);
--  if( !p && db ){
--    db->mallocFailed = 1;
--  }
--  sqlite3MemdebugSetType(p, MEMTYPE_DB |
--         ((db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
--  return p;
--}
--
--/*
--** 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){
--  void *pNew = 0;
--  assert( db!=0 );
--  assert( sqlite3_mutex_held(db->mutex) );
--  if( db->mallocFailed==0 ){
--    if( p==0 ){
--      return sqlite3DbMallocRaw(db, n);
-+  memsys3Enter();
-+  fprintf(out, "CHUNKS:\n");
-+  for(i=1; i<=mem3.nPool; i+=size/4){
-+    size = mem3.aPool[i-1].u.hdr.size4x;
-+    if( size/4<=1 ){
-+      fprintf(out, "%p size error\n", &mem3.aPool[i]);
-+      assert( 0 );
-+      break;
-     }
--    if( isLookaside(db, p) ){
--      if( n<=db->lookaside.sz ){
--        return p;
--      }
--      pNew = sqlite3DbMallocRaw(db, n);
--      if( pNew ){
--        memcpy(pNew, p, db->lookaside.sz);
--        sqlite3DbFree(db, p);
--      }
-+    if( (size&1)==0 && mem3.aPool[i+size/4-1].u.hdr.prevSize!=size/4 ){
-+      fprintf(out, "%p tail size does not match\n", &mem3.aPool[i]);
-+      assert( 0 );
-+      break;
-+    }
-+    if( ((mem3.aPool[i+size/4-1].u.hdr.size4x&2)>>1)!=(size&1) ){
-+      fprintf(out, "%p tail checkout bit is incorrect\n", &mem3.aPool[i]);
-+      assert( 0 );
-+      break;
-+    }
-+    if( size&1 ){
-+      fprintf(out, "%p %6d bytes checked out\n", &mem3.aPool[i], (size/4)*8-8);
-     }else{
--      assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
--      assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
--      sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
--      pNew = sqlite3_realloc(p, n);
--      if( !pNew ){
--        sqlite3MemdebugSetType(p, MEMTYPE_DB|MEMTYPE_HEAP);
--        db->mallocFailed = 1;
--      }
--      sqlite3MemdebugSetType(pNew, MEMTYPE_DB | 
--            (db->lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
-+      fprintf(out, "%p %6d bytes free%s\n", &mem3.aPool[i], (size/4)*8-8,
-+                  i==mem3.iMaster ? " **master**" : "");
-     }
-   }
--  return pNew;
-+  for(i=0; i<MX_SMALL-1; i++){
-+    if( mem3.aiSmall[i]==0 ) continue;
-+    fprintf(out, "small(%2d):", i);
-+    for(j = mem3.aiSmall[i]; j>0; j=mem3.aPool[j].u.list.next){
-+      fprintf(out, " %p(%d)", &mem3.aPool[j],
-+              (mem3.aPool[j-1].u.hdr.size4x/4)*8-8);
-+    }
-+    fprintf(out, "\n"); 
-+  }
-+  for(i=0; i<N_HASH; i++){
-+    if( mem3.aiHash[i]==0 ) continue;
-+    fprintf(out, "hash(%2d):", i);
-+    for(j = mem3.aiHash[i]; j>0; j=mem3.aPool[j].u.list.next){
-+      fprintf(out, " %p(%d)", &mem3.aPool[j],
-+              (mem3.aPool[j-1].u.hdr.size4x/4)*8-8);
-+    }
-+    fprintf(out, "\n"); 
-+  }
-+  fprintf(out, "master=%d\n", mem3.iMaster);
-+  fprintf(out, "nowUsed=%d\n", mem3.nPool*8 - mem3.szMaster*8);
-+  fprintf(out, "mxUsed=%d\n", mem3.nPool*8 - mem3.mnMaster*8);
-+  sqlite3_mutex_leave(mem3.mutex);
-+  if( out==stdout ){
-+    fflush(stdout);
-+  }else{
-+    fclose(out);
-+  }
-+#else
-+  UNUSED_PARAMETER(zFilename);
-+#endif
- }
- 
- /*
--** Attempt to reallocate p.  If the reallocation fails, then free p
--** and set the mallocFailed flag in the database connection.
-+** This routine is the only routine in this file with external 
-+** linkage.
-+**
-+** 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 void *sqlite3DbReallocOrFree(sqlite3 *db, void *p, int n){
--  void *pNew;
--  pNew = sqlite3DbRealloc(db, p, n);
--  if( !pNew ){
--    sqlite3DbFree(db, p);
--  }
--  return pNew;
-+SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void){
-+  static const sqlite3_mem_methods mempoolMethods = {
-+     memsys3Malloc,
-+     memsys3Free,
-+     memsys3Realloc,
-+     memsys3Size,
-+     memsys3Roundup,
-+     memsys3Init,
-+     memsys3Shutdown,
-+     0
-+  };
-+  return &mempoolMethods;
- }
- 
-+#endif /* SQLITE_ENABLE_MEMSYS3 */
-+
-+/************** End of mem3.c ************************************************/
-+/************** Begin file mem5.c ********************************************/
- /*
--** Make a copy of a string in memory obtained from sqliteMalloc(). These 
--** functions call sqlite3MallocRaw() directly instead of sqliteMalloc(). This
--** is because when memory debugging is turned on, these two functions are 
--** called via macros that record the current file and line number in the
--** ThreadData structure.
-+** 2007 October 14
-+**
-+** 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 a memory
-+** allocation subsystem for use by SQLite. 
-+**
-+** This version of the memory allocation subsystem omits all
-+** use of malloc(). The application gives SQLite a block of memory
-+** before calling sqlite3_initialize() from which allocations
-+** are made and returned by the xMalloc() and xRealloc() 
-+** implementations. Once sqlite3_initialize() has been called,
-+** the amount of memory available to SQLite is fixed and cannot
-+** be changed.
-+**
-+** This version of the memory allocation subsystem is included
-+** in the build only if SQLITE_ENABLE_MEMSYS5 is defined.
-+**
-+** This memory allocator uses the following algorithm:
-+**
-+**   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.
-+**
-+**   3.  New memory is allocated from the first available free block.
-+**
-+** This algorithm is described in: J. M. Robson. "Bounds for Some Functions
-+** Concerning Dynamic Storage Allocation". Journal of the Association for
-+** Computing Machinery, Volume 21, Number 8, July 1974, pages 491-499.
-+** 
-+** Let n be the size of the largest allocation divided by the minimum
-+** allocation size (after rounding all sizes up to a power of 2.)  Let M
-+** be the maximum amount of memory ever outstanding at one time.  Let
-+** N be the total amount of memory available for allocation.  Robson
-+** proved that this memory allocator will never breakdown due to 
-+** fragmentation as long as the following constraint holds:
-+**
-+**      N >=  M*(1 + log2(n)/2) - n + 1
-+**
-+** The sqlite3_status() logic tracks the maximum values of n and M so
-+** that an application can, at any time, verify this constraint.
- */
--SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3 *db, const char *z){
--  char *zNew;
--  size_t n;
--  if( z==0 ){
--    return 0;
--  }
--  n = sqlite3Strlen30(z) + 1;
--  assert( (n&0x7fffffff)==n );
--  zNew = sqlite3DbMallocRaw(db, (int)n);
--  if( zNew ){
--    memcpy(zNew, z, n);
--  }
--  return zNew;
--}
--SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3 *db, const char *z, int n){
--  char *zNew;
--  if( z==0 ){
--    return 0;
--  }
--  assert( (n&0x7fffffff)==n );
--  zNew = sqlite3DbMallocRaw(db, n+1);
--  if( zNew ){
--    memcpy(zNew, z, n);
--    zNew[n] = 0;
--  }
--  return zNew;
--}
- 
- /*
--** Create a string from the zFromat argument and the va_list that follows.
--** Store the string in memory obtained from sqliteMalloc() and make *pz
--** point to that string.
-+** This version of the memory allocator is used only when 
-+** SQLITE_ENABLE_MEMSYS5 is defined.
- */
--SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zFormat, ...){
--  va_list ap;
--  char *z;
--
--  va_start(ap, zFormat);
--  z = sqlite3VMPrintf(db, zFormat, ap);
--  va_end(ap);
--  sqlite3DbFree(db, *pz);
--  *pz = z;
--}
--
-+#ifdef SQLITE_ENABLE_MEMSYS5
- 
- /*
--** This function must be called before exiting any API function (i.e. 
--** returning control to the user) that has called sqlite3_malloc or
--** sqlite3_realloc.
--**
--** The returned value is normally a copy of the second argument to this
--** function. However, if a malloc() failure has occurred since the previous
--** invocation SQLITE_NOMEM is returned instead. 
-+** A minimum allocation is an instance of the following structure.
-+** Larger allocations are an array of these structures where the
-+** size of the array is a power of 2.
- **
--** If the first argument, db, is not NULL and a malloc() error has occurred,
--** then the connection error-code (the value returned by sqlite3_errcode())
--** is set to SQLITE_NOMEM.
-+** The size of this object must be a power of two.  That fact is
-+** verified in memsys5Init().
- */
--SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){
--  /* If the db handle is not NULL, then we must hold the connection handle
--  ** mutex here. Otherwise the read (and possible write) of db->mallocFailed 
--  ** 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;
--  }
--  return rc & (db ? db->errMask : 0xff);
--}
-+typedef struct Mem5Link Mem5Link;
-+struct Mem5Link {
-+  int next;       /* Index of next free chunk */
-+  int prev;       /* Index of previous free chunk */
-+};
- 
--/************** End of malloc.c **********************************************/
--/************** Begin file printf.c ******************************************/
- /*
--** The "printf" code that follows dates from the 1980's.  It is in
--** the public domain.  The original comments are included here for
--** completeness.  They are very out-of-date but might be useful as
--** an historical reference.  Most of the "enhancements" have been backed
--** out so that the functionality is now the same as standard printf().
--**
--**************************************************************************
--**
--** This file contains code for a set of "printf"-like routines.  These
--** routines format strings much like the printf() from the standard C
--** library, though the implementation here has enhancements to support
--** SQLlite.
-+** Maximum size of any allocation is ((1<<LOGMAX)*mem5.szAtom). Since
-+** mem5.szAtom is always at least 8 and 32-bit integers are used,
-+** it is not actually possible to reach this limit.
- */
-+#define LOGMAX 30
- 
- /*
--** Conversion types fall into various categories as defined by the
--** following enumeration.
-+** Masks used for mem5.aCtrl[] elements.
- */
--#define etRADIX       1 /* Integer types.  %d, %x, %o, and so forth */
--#define etFLOAT       2 /* Floating point.  %f */
--#define etEXP         3 /* Exponentional notation. %e and %E */
--#define etGENERIC     4 /* Floating or exponential, depending on exponent. %g */
--#define etSIZE        5 /* Return number of characters processed so far. %n */
--#define etSTRING      6 /* Strings. %s */
--#define etDYNSTRING   7 /* Dynamically allocated strings. %z */
--#define etPERCENT     8 /* Percent symbol. %% */
--#define etCHARX       9 /* Characters. %c */
--/* The rest are extensions, not normally found in printf() */
--#define etSQLESCAPE  10 /* Strings with '\'' doubled.  %q */
--#define etSQLESCAPE2 11 /* Strings with '\'' doubled and enclosed in '',
--                          NULL pointers replaced by SQL NULL.  %Q */
--#define etTOKEN      12 /* a pointer to a Token structure */
--#define etSRCLIST    13 /* a pointer to a SrcList */
--#define etPOINTER    14 /* The %p conversion */
--#define etSQLESCAPE3 15 /* %w -> Strings with '\"' doubled */
--#define etORDINAL    16 /* %r -> 1st, 2nd, 3rd, 4th, etc.  English only */
-+#define CTRL_LOGSIZE  0x1f    /* Log2 Size of this block */
-+#define CTRL_FREE     0x20    /* True if not checked out */
- 
--#define etINVALID     0 /* Any unrecognized conversion type */
-+/*
-+** All of the static variables used by this module are collected
-+** into a single structure named "mem5".  This is to keep the
-+** static variables organized and to reduce namespace pollution
-+** when this module is combined with other in the amalgamation.
-+*/
-+static SQLITE_WSD struct Mem5Global {
-+  /*
-+  ** Memory available for allocation
-+  */
-+  int szAtom;      /* Smallest possible allocation in bytes */
-+  int nBlock;      /* Number of szAtom sized blocks in zPool */
-+  u8 *zPool;       /* Memory available to be allocated */
-+  
-+  /*
-+  ** Mutex to control access to the memory allocation subsystem.
-+  */
-+  sqlite3_mutex *mutex;
-+
-+  /*
-+  ** Performance statistics
-+  */
-+  u64 nAlloc;         /* Total number of calls to malloc */
-+  u64 totalAlloc;     /* Total of all malloc calls - includes internal frag */
-+  u64 totalExcess;    /* Total internal fragmentation */
-+  u32 currentOut;     /* Current checkout, including internal fragmentation */
-+  u32 currentCount;   /* Current number of distinct checkouts */
-+  u32 maxOut;         /* Maximum instantaneous currentOut */
-+  u32 maxCount;       /* Maximum instantaneous currentCount */
-+  u32 maxRequest;     /* Largest allocation (exclusive of internal frag) */
-+  
-+  /*
-+  ** Lists of free blocks.  aiFreelist[0] is a list of free blocks of
-+  ** size mem5.szAtom.  aiFreelist[1] holds blocks of size szAtom*2.
-+  ** and so forth.
-+  */
-+  int aiFreelist[LOGMAX+1];
-+
-+  /*
-+  ** Space for tracking which blocks are checked out and the size
-+  ** of each block.  One byte per block.
-+  */
-+  u8 *aCtrl;
- 
-+} mem5;
- 
- /*
--** An "etByte" is an 8-bit unsigned value.
-+** Access the static variable through a macro for SQLITE_OMIT_WSD
- */
--typedef unsigned char etByte;
-+#define mem5 GLOBAL(struct Mem5Global, mem5)
- 
- /*
--** Each builtin conversion character (ex: the 'd' in "%d") is described
--** by an instance of the following structure
-+** Assuming mem5.zPool is divided up into an array of Mem5Link
-+** structures, return a pointer to the idx-th such lik.
- */
--typedef struct et_info {   /* Information about each format field */
--  char fmttype;            /* The format field code letter */
--  etByte base;             /* The base for radix conversion */
--  etByte flags;            /* One or more of FLAG_ constants below */
--  etByte type;             /* Conversion paradigm */
--  etByte charset;          /* Offset into aDigits[] of the digits string */
--  etByte prefix;           /* Offset into aPrefix[] of the prefix string */
--} et_info;
-+#define MEM5LINK(idx) ((Mem5Link *)(&mem5.zPool[(idx)*mem5.szAtom]))
- 
- /*
--** Allowed values for et_info.flags
-+** Unlink the chunk at mem5.aPool[i] from list it is currently
-+** on.  It should be found on mem5.aiFreelist[iLogsize].
- */
--#define FLAG_SIGNED  1     /* True if the value to convert is signed */
--#define FLAG_INTERN  2     /* True if for internal use only */
--#define FLAG_STRING  4     /* Allow infinity precision */
-+static void memsys5Unlink(int i, int iLogsize){
-+  int next, prev;
-+  assert( i>=0 && i<mem5.nBlock );
-+  assert( iLogsize>=0 && iLogsize<=LOGMAX );
-+  assert( (mem5.aCtrl[i] & CTRL_LOGSIZE)==iLogsize );
- 
-+  next = MEM5LINK(i)->next;
-+  prev = MEM5LINK(i)->prev;
-+  if( prev<0 ){
-+    mem5.aiFreelist[iLogsize] = next;
-+  }else{
-+    MEM5LINK(prev)->next = next;
-+  }
-+  if( next>=0 ){
-+    MEM5LINK(next)->prev = prev;
-+  }
-+}
- 
- /*
--** The following table is searched linearly, so it is good to put the
--** most frequently used conversion types first.
-+** Link the chunk at mem5.aPool[i] so that is on the iLogsize
-+** free list.
- */
--static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
--static const char aPrefix[] = "-x0\000X0";
--static const et_info fmtinfo[] = {
--  {  'd', 10, 1, etRADIX,      0,  0 },
--  {  's',  0, 4, etSTRING,     0,  0 },
--  {  'g',  0, 1, etGENERIC,    30, 0 },
--  {  'z',  0, 4, etDYNSTRING,  0,  0 },
--  {  'q',  0, 4, etSQLESCAPE,  0,  0 },
--  {  'Q',  0, 4, etSQLESCAPE2, 0,  0 },
--  {  'w',  0, 4, etSQLESCAPE3, 0,  0 },
--  {  'c',  0, 0, etCHARX,      0,  0 },
--  {  'o',  8, 0, etRADIX,      0,  2 },
--  {  'u', 10, 0, etRADIX,      0,  0 },
--  {  'x', 16, 0, etRADIX,      16, 1 },
--  {  'X', 16, 0, etRADIX,      0,  4 },
--#ifndef SQLITE_OMIT_FLOATING_POINT
--  {  'f',  0, 1, etFLOAT,      0,  0 },
--  {  'e',  0, 1, etEXP,        30, 0 },
--  {  'E',  0, 1, etEXP,        14, 0 },
--  {  'G',  0, 1, etGENERIC,    14, 0 },
--#endif
--  {  'i', 10, 1, etRADIX,      0,  0 },
--  {  'n',  0, 0, etSIZE,       0,  0 },
--  {  '%',  0, 0, etPERCENT,    0,  0 },
--  {  'p', 16, 0, etPOINTER,    0,  1 },
-+static void memsys5Link(int i, int iLogsize){
-+  int x;
-+  assert( sqlite3_mutex_held(mem5.mutex) );
-+  assert( i>=0 && i<mem5.nBlock );
-+  assert( iLogsize>=0 && iLogsize<=LOGMAX );
-+  assert( (mem5.aCtrl[i] & CTRL_LOGSIZE)==iLogsize );
- 
--/* All the rest have the FLAG_INTERN bit set and are thus for internal
--** use only */
--  {  'T',  0, 2, etTOKEN,      0,  0 },
--  {  'S',  0, 2, etSRCLIST,    0,  0 },
--  {  'r', 10, 3, etORDINAL,    0,  0 },
--};
-+  x = MEM5LINK(i)->next = mem5.aiFreelist[iLogsize];
-+  MEM5LINK(i)->prev = -1;
-+  if( x>=0 ){
-+    assert( x<mem5.nBlock );
-+    MEM5LINK(x)->prev = i;
-+  }
-+  mem5.aiFreelist[iLogsize] = i;
-+}
- 
- /*
--** If SQLITE_OMIT_FLOATING_POINT is defined, then none of the floating point
--** conversions will work.
-+** If the STATIC_MEM mutex is not already held, obtain it now. The mutex
-+** will already be held (obtained by code in malloc.c) if
-+** sqlite3GlobalConfig.bMemStat is true.
- */
--#ifndef SQLITE_OMIT_FLOATING_POINT
-+static void memsys5Enter(void){
-+  sqlite3_mutex_enter(mem5.mutex);
-+}
-+static void memsys5Leave(void){
-+  sqlite3_mutex_leave(mem5.mutex);
-+}
-+
- /*
--** "*val" is a double such that 0.1 <= *val < 10.0
--** Return the ascii code for the leading digit of *val, then
--** multiply "*val" by 10.0 to renormalize.
--**
--** Example:
--**     input:     *val = 3.14159
--**     output:    *val = 1.4159    function return = '3'
--**
--** The counter *cnt is incremented each time.  After counter exceeds
--** 16 (the number of significant digits in a 64-bit float) '0' is
--** always returned.
-+** Return the size of an outstanding allocation, in bytes.  The
-+** size returned omits the 8-byte header overhead.  This only
-+** works for chunks that are currently checked out.
- */
--static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
--  int digit;
--  LONGDOUBLE_TYPE d;
--  if( (*cnt)<=0 ) return '0';
--  (*cnt)--;
--  digit = (int)*val;
--  d = digit;
--  digit += '0';
--  *val = (*val - d)*10.0;
--  return (char)digit;
-+static int memsys5Size(void *p){
-+  int iSize = 0;
-+  if( p ){
-+    int i = ((u8 *)p-mem5.zPool)/mem5.szAtom;
-+    assert( i>=0 && i<mem5.nBlock );
-+    iSize = mem5.szAtom * (1 << (mem5.aCtrl[i]&CTRL_LOGSIZE));
-+  }
-+  return iSize;
- }
--#endif /* SQLITE_OMIT_FLOATING_POINT */
- 
- /*
--** Append N space characters to the given string buffer.
-+** Find the first entry on the freelist iLogsize.  Unlink that
-+** entry and return its index. 
- */
--SQLITE_PRIVATE void sqlite3AppendSpace(StrAccum *pAccum, int N){
--  static const char zSpaces[] = "                             ";
--  while( N>=(int)sizeof(zSpaces)-1 ){
--    sqlite3StrAccumAppend(pAccum, zSpaces, sizeof(zSpaces)-1);
--    N -= sizeof(zSpaces)-1;
--  }
--  if( N>0 ){
--    sqlite3StrAccumAppend(pAccum, zSpaces, N);
-+static int memsys5UnlinkFirst(int iLogsize){
-+  int i;
-+  int iFirst;
-+
-+  assert( iLogsize>=0 && iLogsize<=LOGMAX );
-+  i = iFirst = mem5.aiFreelist[iLogsize];
-+  assert( iFirst>=0 );
-+  while( i>0 ){
-+    if( i<iFirst ) iFirst = i;
-+    i = MEM5LINK(i)->next;
-   }
-+  memsys5Unlink(iFirst, iLogsize);
-+  return iFirst;
- }
- 
- /*
--** On machines with a small stack size, you can redefine the
--** SQLITE_PRINT_BUF_SIZE to be something smaller, if desired.
-+** Return a block of memory of at least nBytes in size.
-+** Return NULL if unable.  Return NULL if nBytes==0.
-+**
-+** The caller guarantees that nByte positive.
-+**
-+** The caller has obtained a mutex prior to invoking this
-+** routine so there is never any chance that two or more
-+** threads can be in this routine at the same time.
- */
--#ifndef SQLITE_PRINT_BUF_SIZE
--# define SQLITE_PRINT_BUF_SIZE 70
--#endif
--#define etBUFSIZE SQLITE_PRINT_BUF_SIZE  /* Size of the output buffer */
-+static void *memsys5MallocUnsafe(int nByte){
-+  int i;           /* Index of a mem5.aPool[] slot */
-+  int iBin;        /* Index into mem5.aiFreelist[] */
-+  int iFullSz;     /* Size of allocation rounded up to power of 2 */
-+  int iLogsize;    /* Log2 of iFullSz/POW2_MIN */
-+
-+  /* nByte must be a positive */
-+  assert( nByte>0 );
-+
-+  /* Keep track of the maximum allocation request.  Even unfulfilled
-+  ** requests are counted */
-+  if( (u32)nByte>mem5.maxRequest ){
-+    mem5.maxRequest = nByte;
-+  }
-+
-+  /* Abort if the requested allocation size is larger than the largest
-+  ** power of two that we can represent using 32-bit signed integers.
-+  */
-+  if( nByte > 0x40000000 ){
-+    return 0;
-+  }
-+
-+  /* Round nByte up to the next valid power of two */
-+  for(iFullSz=mem5.szAtom, iLogsize=0; iFullSz<nByte; iFullSz *= 2, iLogsize++){}
-+
-+  /* Make sure mem5.aiFreelist[iLogsize] contains at least one free
-+  ** block.  If not, then split a block of the next larger power of
-+  ** two in order to create a new free block of size iLogsize.
-+  */
-+  for(iBin=iLogsize; mem5.aiFreelist[iBin]<0 && iBin<=LOGMAX; iBin++){}
-+  if( iBin>LOGMAX ){
-+    testcase( sqlite3GlobalConfig.xLog!=0 );
-+    sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes", nByte);
-+    return 0;
-+  }
-+  i = memsys5UnlinkFirst(iBin);
-+  while( iBin>iLogsize ){
-+    int newSize;
-+
-+    iBin--;
-+    newSize = 1 << iBin;
-+    mem5.aCtrl[i+newSize] = CTRL_FREE | iBin;
-+    memsys5Link(i+newSize, iBin);
-+  }
-+  mem5.aCtrl[i] = iLogsize;
-+
-+  /* Update allocator performance statistics. */
-+  mem5.nAlloc++;
-+  mem5.totalAlloc += iFullSz;
-+  mem5.totalExcess += iFullSz - nByte;
-+  mem5.currentCount++;
-+  mem5.currentOut += iFullSz;
-+  if( mem5.maxCount<mem5.currentCount ) mem5.maxCount = mem5.currentCount;
-+  if( mem5.maxOut<mem5.currentOut ) mem5.maxOut = mem5.currentOut;
-+
-+  /* Return a pointer to the allocated memory. */
-+  return (void*)&mem5.zPool[i*mem5.szAtom];
-+}
- 
- /*
--** Render a string given by "fmt" into the StrAccum object.
-+** Free an outstanding memory allocation.
- */
--SQLITE_PRIVATE void sqlite3VXPrintf(
--  StrAccum *pAccum,                  /* Accumulate results here */
--  int useExtended,                   /* Allow extended %-conversions */
--  const char *fmt,                   /* Format string */
--  va_list ap                         /* arguments */
--){
--  int c;                     /* Next character in the format string */
--  char *bufpt;               /* Pointer to the conversion buffer */
--  int precision;             /* Precision of the current field */
--  int length;                /* Length of the field */
--  int idx;                   /* A general purpose loop counter */
--  int width;                 /* Width of the current field */
--  etByte flag_leftjustify;   /* True if "-" flag is present */
--  etByte flag_plussign;      /* True if "+" flag is present */
--  etByte flag_blanksign;     /* True if " " flag is present */
--  etByte flag_alternateform; /* True if "#" flag is present */
--  etByte flag_altform2;      /* True if "!" flag is present */
--  etByte flag_zeropad;       /* True if field width constant starts with zero */
--  etByte flag_long;          /* True if "l" flag is present */
--  etByte flag_longlong;      /* True if the "ll" flag is present */
--  etByte done;               /* Loop termination flag */
--  etByte xtype = 0;          /* Conversion paradigm */
--  char prefix;               /* Prefix character.  "+" or "-" or " " or '\0'. */
--  sqlite_uint64 longvalue;   /* Value for integer types */
--  LONGDOUBLE_TYPE realvalue; /* Value for real types */
--  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 */
--#ifndef SQLITE_OMIT_FLOATING_POINT
--  int  exp, e2;              /* exponent of real numbers */
--  int nsd;                   /* Number of significant digits returned */
--  double rounder;            /* Used for rounding floating point values */
--  etByte flag_dp;            /* True if decimal point should be shown */
--  etByte flag_rtz;           /* True if trailing zeros should be removed */
--#endif
--  char buf[etBUFSIZE];       /* Conversion buffer */
-+static void memsys5FreeUnsafe(void *pOld){
-+  u32 size, iLogsize;
-+  int iBlock;
- 
--  bufpt = 0;
--  for(; (c=(*fmt))!=0; ++fmt){
--    if( c!='%' ){
--      int amt;
--      bufpt = (char *)fmt;
--      amt = 1;
--      while( (c=(*++fmt))!='%' && c!=0 ) amt++;
--      sqlite3StrAccumAppend(pAccum, bufpt, amt);
--      if( c==0 ) break;
--    }
--    if( (c=(*++fmt))==0 ){
--      sqlite3StrAccumAppend(pAccum, "%", 1);
--      break;
--    }
--    /* Find out what flags are present */
--    flag_leftjustify = flag_plussign = flag_blanksign = 
--     flag_alternateform = flag_altform2 = flag_zeropad = 0;
--    done = 0;
--    do{
--      switch( c ){
--        case '-':   flag_leftjustify = 1;     break;
--        case '+':   flag_plussign = 1;        break;
--        case ' ':   flag_blanksign = 1;       break;
--        case '#':   flag_alternateform = 1;   break;
--        case '!':   flag_altform2 = 1;        break;
--        case '0':   flag_zeropad = 1;         break;
--        default:    done = 1;                 break;
--      }
--    }while( !done && (c=(*++fmt))!=0 );
--    /* Get the field width */
--    width = 0;
--    if( c=='*' ){
--      width = va_arg(ap,int);
--      if( width<0 ){
--        flag_leftjustify = 1;
--        width = -width;
--      }
--      c = *++fmt;
-+  /* Set iBlock to the index of the block pointed to by pOld in 
-+  ** the array of mem5.szAtom byte blocks pointed to by mem5.zPool.
-+  */
-+  iBlock = ((u8 *)pOld-mem5.zPool)/mem5.szAtom;
-+
-+  /* Check that the pointer pOld points to a valid, non-free block. */
-+  assert( iBlock>=0 && iBlock<mem5.nBlock );
-+  assert( ((u8 *)pOld-mem5.zPool)%mem5.szAtom==0 );
-+  assert( (mem5.aCtrl[iBlock] & CTRL_FREE)==0 );
-+
-+  iLogsize = mem5.aCtrl[iBlock] & CTRL_LOGSIZE;
-+  size = 1<<iLogsize;
-+  assert( iBlock+size-1<(u32)mem5.nBlock );
-+
-+  mem5.aCtrl[iBlock] |= CTRL_FREE;
-+  mem5.aCtrl[iBlock+size-1] |= CTRL_FREE;
-+  assert( mem5.currentCount>0 );
-+  assert( mem5.currentOut>=(size*mem5.szAtom) );
-+  mem5.currentCount--;
-+  mem5.currentOut -= size*mem5.szAtom;
-+  assert( mem5.currentOut>0 || mem5.currentCount==0 );
-+  assert( mem5.currentCount>0 || mem5.currentOut==0 );
-+
-+  mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize;
-+  while( ALWAYS(iLogsize<LOGMAX) ){
-+    int iBuddy;
-+    if( (iBlock>>iLogsize) & 1 ){
-+      iBuddy = iBlock - size;
-     }else{
--      while( c>='0' && c<='9' ){
--        width = width*10 + c - '0';
--        c = *++fmt;
--      }
-+      iBuddy = iBlock + size;
-     }
--    /* Get the precision */
--    if( c=='.' ){
--      precision = 0;
--      c = *++fmt;
--      if( c=='*' ){
--        precision = va_arg(ap,int);
--        if( precision<0 ) precision = -precision;
--        c = *++fmt;
--      }else{
--        while( c>='0' && c<='9' ){
--          precision = precision*10 + c - '0';
--          c = *++fmt;
--        }
--      }
-+    assert( iBuddy>=0 );
-+    if( (iBuddy+(1<<iLogsize))>mem5.nBlock ) break;
-+    if( mem5.aCtrl[iBuddy]!=(CTRL_FREE | iLogsize) ) break;
-+    memsys5Unlink(iBuddy, iLogsize);
-+    iLogsize++;
-+    if( iBuddy<iBlock ){
-+      mem5.aCtrl[iBuddy] = CTRL_FREE | iLogsize;
-+      mem5.aCtrl[iBlock] = 0;
-+      iBlock = iBuddy;
-     }else{
--      precision = -1;
-+      mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize;
-+      mem5.aCtrl[iBuddy] = 0;
-     }
--    /* Get the conversion type modifier */
--    if( c=='l' ){
--      flag_long = 1;
--      c = *++fmt;
--      if( c=='l' ){
--        flag_longlong = 1;
--        c = *++fmt;
--      }else{
--        flag_longlong = 0;
--      }
--    }else{
--      flag_long = flag_longlong = 0;
-+    size *= 2;
-+  }
-+  memsys5Link(iBlock, iLogsize);
-+}
-+
-+/*
-+** Allocate nBytes of memory
-+*/
-+static void *memsys5Malloc(int nBytes){
-+  sqlite3_int64 *p = 0;
-+  if( nBytes>0 ){
-+    memsys5Enter();
-+    p = memsys5MallocUnsafe(nBytes);
-+    memsys5Leave();
-+  }
-+  return (void*)p; 
-+}
-+
-+/*
-+** Free memory.
-+**
-+** The outer layer memory allocator prevents this routine from
-+** being called with pPrior==0.
-+*/
-+static void memsys5Free(void *pPrior){
-+  assert( pPrior!=0 );
-+  memsys5Enter();
-+  memsys5FreeUnsafe(pPrior);
-+  memsys5Leave();  
-+}
-+
-+/*
-+** Change the size of an existing memory allocation.
-+**
-+** The outer layer memory allocator prevents this routine from
-+** being called with pPrior==0.  
-+**
-+** nBytes is always a value obtained from a prior call to
-+** memsys5Round().  Hence nBytes is always a non-negative power
-+** of two.  If nBytes==0 that means that an oversize allocation
-+** (an allocation larger than 0x40000000) was requested and this
-+** routine should return 0 without freeing pPrior.
-+*/
-+static void *memsys5Realloc(void *pPrior, int nBytes){
-+  int nOld;
-+  void *p;
-+  assert( pPrior!=0 );
-+  assert( (nBytes&(nBytes-1))==0 );  /* EV: R-46199-30249 */
-+  assert( nBytes>=0 );
-+  if( nBytes==0 ){
-+    return 0;
-+  }
-+  nOld = memsys5Size(pPrior);
-+  if( nBytes<=nOld ){
-+    return pPrior;
-+  }
-+  memsys5Enter();
-+  p = memsys5MallocUnsafe(nBytes);
-+  if( p ){
-+    memcpy(p, pPrior, nOld);
-+    memsys5FreeUnsafe(pPrior);
-+  }
-+  memsys5Leave();
-+  return p;
-+}
-+
-+/*
-+** Round up a request size to the next valid allocation size.  If
-+** the allocation is too large to be handled by this allocation system,
-+** return 0.
-+**
-+** All allocations must be a power of two and must be expressed by a
-+** 32-bit signed integer.  Hence the largest allocation is 0x40000000
-+** or 1073741824 bytes.
-+*/
-+static int memsys5Roundup(int n){
-+  int iFullSz;
-+  if( n > 0x40000000 ) return 0;
-+  for(iFullSz=mem5.szAtom; iFullSz<n; iFullSz *= 2);
-+  return iFullSz;
-+}
-+
-+/*
-+** Return the ceiling of the logarithm base 2 of iValue.
-+**
-+** Examples:   memsys5Log(1) -> 0
-+**             memsys5Log(2) -> 1
-+**             memsys5Log(4) -> 2
-+**             memsys5Log(5) -> 3
-+**             memsys5Log(8) -> 3
-+**             memsys5Log(9) -> 4
-+*/
-+static int memsys5Log(int iValue){
-+  int iLog;
-+  for(iLog=0; (iLog<(int)((sizeof(int)*8)-1)) && (1<<iLog)<iValue; iLog++);
-+  return iLog;
-+}
-+
-+/*
-+** Initialize the memory allocator.
-+**
-+** This routine is not threadsafe.  The caller must be holding a mutex
-+** to prevent multiple threads from entering at the same time.
-+*/
-+static int memsys5Init(void *NotUsed){
-+  int ii;            /* Loop counter */
-+  int nByte;         /* Number of bytes of memory available to this allocator */
-+  u8 *zByte;         /* Memory usable by this allocator */
-+  int nMinLog;       /* Log base 2 of minimum allocation size in bytes */
-+  int iOffset;       /* An offset into mem5.aCtrl[] */
-+
-+  UNUSED_PARAMETER(NotUsed);
-+
-+  /* For the purposes of this routine, disable the mutex */
-+  mem5.mutex = 0;
-+
-+  /* The size of a Mem5Link object must be a power of two.  Verify that
-+  ** this is case.
-+  */
-+  assert( (sizeof(Mem5Link)&(sizeof(Mem5Link)-1))==0 );
-+
-+  nByte = sqlite3GlobalConfig.nHeap;
-+  zByte = (u8*)sqlite3GlobalConfig.pHeap;
-+  assert( zByte!=0 );  /* sqlite3_config() does not allow otherwise */
-+
-+  /* boundaries on sqlite3GlobalConfig.mnReq are enforced in sqlite3_config() */
-+  nMinLog = memsys5Log(sqlite3GlobalConfig.mnReq);
-+  mem5.szAtom = (1<<nMinLog);
-+  while( (int)sizeof(Mem5Link)>mem5.szAtom ){
-+    mem5.szAtom = mem5.szAtom << 1;
-+  }
-+
-+  mem5.nBlock = (nByte / (mem5.szAtom+sizeof(u8)));
-+  mem5.zPool = zByte;
-+  mem5.aCtrl = (u8 *)&mem5.zPool[mem5.nBlock*mem5.szAtom];
-+
-+  for(ii=0; ii<=LOGMAX; ii++){
-+    mem5.aiFreelist[ii] = -1;
-+  }
-+
-+  iOffset = 0;
-+  for(ii=LOGMAX; ii>=0; ii--){
-+    int nAlloc = (1<<ii);
-+    if( (iOffset+nAlloc)<=mem5.nBlock ){
-+      mem5.aCtrl[iOffset] = ii | CTRL_FREE;
-+      memsys5Link(iOffset, ii);
-+      iOffset += nAlloc;
-     }
--    /* Fetch the info entry for the field */
--    infop = &fmtinfo[0];
--    xtype = etINVALID;
--    for(idx=0; idx<ArraySize(fmtinfo); idx++){
--      if( c==fmtinfo[idx].fmttype ){
--        infop = &fmtinfo[idx];
--        if( useExtended || (infop->flags & FLAG_INTERN)==0 ){
--          xtype = infop->type;
--        }else{
--          return;
--        }
--        break;
--      }
-+    assert((iOffset+nAlloc)>mem5.nBlock);
-+  }
-+
-+  /* If a mutex is required for normal operation, allocate one */
-+  if( sqlite3GlobalConfig.bMemstat==0 ){
-+    mem5.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
-+  }
-+
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** Deinitialize this module.
-+*/
-+static void memsys5Shutdown(void *NotUsed){
-+  UNUSED_PARAMETER(NotUsed);
-+  mem5.mutex = 0;
-+  return;
-+}
-+
-+#ifdef SQLITE_TEST
-+/*
-+** Open the file indicated and write a log of all unfreed memory 
-+** allocations into that log.
-+*/
-+SQLITE_PRIVATE void sqlite3Memsys5Dump(const char *zFilename){
-+  FILE *out;
-+  int i, j, n;
-+  int nMinLog;
-+
-+  if( zFilename==0 || zFilename[0]==0 ){
-+    out = stdout;
-+  }else{
-+    out = fopen(zFilename, "w");
-+    if( out==0 ){
-+      fprintf(stderr, "** Unable to output memory debug output log: %s **\n",
-+                      zFilename);
-+      return;
-     }
--    zExtra = 0;
-+  }
-+  memsys5Enter();
-+  nMinLog = memsys5Log(mem5.szAtom);
-+  for(i=0; i<=LOGMAX && i+nMinLog<32; i++){
-+    for(n=0, j=mem5.aiFreelist[i]; j>=0; j = MEM5LINK(j)->next, n++){}
-+    fprintf(out, "freelist items of size %d: %d\n", mem5.szAtom << i, n);
-+  }
-+  fprintf(out, "mem5.nAlloc       = %llu\n", mem5.nAlloc);
-+  fprintf(out, "mem5.totalAlloc   = %llu\n", mem5.totalAlloc);
-+  fprintf(out, "mem5.totalExcess  = %llu\n", mem5.totalExcess);
-+  fprintf(out, "mem5.currentOut   = %u\n", mem5.currentOut);
-+  fprintf(out, "mem5.currentCount = %u\n", mem5.currentCount);
-+  fprintf(out, "mem5.maxOut       = %u\n", mem5.maxOut);
-+  fprintf(out, "mem5.maxCount     = %u\n", mem5.maxCount);
-+  fprintf(out, "mem5.maxRequest   = %u\n", mem5.maxRequest);
-+  memsys5Leave();
-+  if( out==stdout ){
-+    fflush(stdout);
-+  }else{
-+    fclose(out);
-+  }
-+}
-+#endif
- 
--    /*
--    ** At this point, variables are initialized as follows:
--    **
--    **   flag_alternateform          TRUE if a '#' is present.
--    **   flag_altform2               TRUE if a '!' is present.
--    **   flag_plussign               TRUE if a '+' is present.
--    **   flag_leftjustify            TRUE if a '-' is present or if the
--    **                               field width was negative.
--    **   flag_zeropad                TRUE if the width began with 0.
--    **   flag_long                   TRUE if the letter 'l' (ell) prefixed
--    **                               the conversion character.
--    **   flag_longlong               TRUE if the letter 'll' (ell ell) prefixed
--    **                               the conversion character.
--    **   flag_blanksign              TRUE if a ' ' is present.
--    **   width                       The specified field width.  This is
--    **                               always non-negative.  Zero is the default.
--    **   precision                   The specified precision.  The default
--    **                               is -1.
--    **   xtype                       The class of the conversion.
--    **   infop                       Pointer to the appropriate info struct.
-+/*
-+** This routine is the only routine in this file with external 
-+** linkage. It returns a pointer to a static sqlite3_mem_methods
-+** struct populated with the memsys5 methods.
-+*/
-+SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void){
-+  static const sqlite3_mem_methods memsys5Methods = {
-+     memsys5Malloc,
-+     memsys5Free,
-+     memsys5Realloc,
-+     memsys5Size,
-+     memsys5Roundup,
-+     memsys5Init,
-+     memsys5Shutdown,
-+     0
-+  };
-+  return &memsys5Methods;
-+}
-+
-+#endif /* SQLITE_ENABLE_MEMSYS5 */
-+
-+/************** End of mem5.c ************************************************/
-+/************** Begin file mutex.c *******************************************/
-+/*
-+** 2007 August 14
++** 2010 February 23
 +**
 +** The author disclaims copyright to this source code.  In place of
 +** a legal notice, here is a blessing:
@@ -14363,49857 +3830,72 @@
 +**    May you share freely, never taking more than you give.
 +**
 +*************************************************************************
-+** This file contains the C functions that implement mutexes.
-+**
-+** This file contains code that is common across all mutex implementations.
-+*/
-+
-+#if defined(SQLITE_DEBUG) && !defined(SQLITE_MUTEX_OMIT)
-+/*
-+** For debugging purposes, record when the mutex subsystem is initialized
-+** and uninitialized so that we can assert() if there is an attempt to
-+** allocate a mutex while the system is uninitialized.
-+*/
-+static SQLITE_WSD int mutexIsInit = 0;
-+#endif /* SQLITE_DEBUG */
-+
-+
-+#ifndef SQLITE_MUTEX_OMIT
-+/*
-+** Initialize the mutex system.
-+*/
-+SQLITE_PRIVATE int sqlite3MutexInit(void){ 
-+  int rc = SQLITE_OK;
-+  if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){
-+    /* If the xMutexAlloc method has not been set, then the user did not
-+    ** install a mutex implementation via sqlite3_config() prior to 
-+    ** sqlite3_initialize() being called. This block copies pointers to
-+    ** the default implementation into the sqlite3GlobalConfig structure.
-     */
--    switch( xtype ){
--      case etPOINTER:
--        flag_longlong = sizeof(char*)==sizeof(i64);
--        flag_long = sizeof(char*)==sizeof(long int);
--        /* Fall through into the next case */
--      case etORDINAL:
--      case etRADIX:
--        if( infop->flags & FLAG_SIGNED ){
--          i64 v;
--          if( flag_longlong ){
--            v = va_arg(ap,i64);
--          }else if( flag_long ){
--            v = va_arg(ap,long int);
--          }else{
--            v = va_arg(ap,int);
--          }
--          if( v<0 ){
--            if( v==SMALLEST_INT64 ){
--              longvalue = ((u64)1)<<63;
--            }else{
--              longvalue = -v;
--            }
--            prefix = '-';
--          }else{
--            longvalue = v;
--            if( flag_plussign )        prefix = '+';
--            else if( flag_blanksign )  prefix = ' ';
--            else                       prefix = 0;
--          }
--        }else{
--          if( flag_longlong ){
--            longvalue = va_arg(ap,u64);
--          }else if( flag_long ){
--            longvalue = va_arg(ap,unsigned long int);
--          }else{
--            longvalue = va_arg(ap,unsigned int);
--          }
--          prefix = 0;
--        }
--        if( longvalue==0 ) flag_alternateform = 0;
--        if( flag_zeropad && precision<width-(prefix!=0) ){
--          precision = width-(prefix!=0);
--        }
--        if( precision<etBUFSIZE-10 ){
--          nOut = etBUFSIZE;
--          zOut = buf;
--        }else{
--          nOut = precision + 10;
--          zOut = zExtra = sqlite3Malloc( nOut );
--          if( zOut==0 ){
--            pAccum->mallocFailed = 1;
--            return;
--          }
--        }
--        bufpt = &zOut[nOut-1];
--        if( xtype==etORDINAL ){
--          static const char zOrd[] = "thstndrd";
--          int x = (int)(longvalue % 10);
--          if( x>=4 || (longvalue/10)%10==1 ){
--            x = 0;
--          }
--          *(--bufpt) = zOrd[x*2+1];
--          *(--bufpt) = zOrd[x*2];
--        }
--        {
--          register const char *cset;      /* Use registers for speed */
--          register int base;
--          cset = &aDigits[infop->charset];
--          base = infop->base;
--          do{                                           /* Convert to ascii */
--            *(--bufpt) = cset[longvalue%base];
--            longvalue = longvalue/base;
--          }while( longvalue>0 );
--        }
--        length = (int)(&zOut[nOut-1]-bufpt);
--        for(idx=precision-length; idx>0; idx--){
--          *(--bufpt) = '0';                             /* Zero pad */
--        }
--        if( prefix ) *(--bufpt) = prefix;               /* Add sign */
--        if( flag_alternateform && infop->prefix ){      /* Add "0" or "0x" */
--          const char *pre;
--          char x;
--          pre = &aPrefix[infop->prefix];
--          for(; (x=(*pre))!=0; pre++) *(--bufpt) = x;
--        }
--        length = (int)(&zOut[nOut-1]-bufpt);
--        break;
--      case etFLOAT:
--      case etEXP:
--      case etGENERIC:
--        realvalue = va_arg(ap,double);
--#ifdef SQLITE_OMIT_FLOATING_POINT
--        length = 0;
--#else
--        if( precision<0 ) precision = 6;         /* Set default precision */
--        if( realvalue<0.0 ){
--          realvalue = -realvalue;
--          prefix = '-';
--        }else{
--          if( flag_plussign )          prefix = '+';
--          else if( flag_blanksign )    prefix = ' ';
--          else                         prefix = 0;
--        }
--        if( xtype==etGENERIC && precision>0 ) precision--;
--#if 0
--        /* Rounding works like BSD when the constant 0.4999 is used.  Wierd! */
--        for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1);
--#else
--        /* It makes more sense to use 0.5 */
--        for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1){}
--#endif
--        if( xtype==etFLOAT ) realvalue += rounder;
--        /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
--        exp = 0;
--        if( sqlite3IsNaN((double)realvalue) ){
--          bufpt = "NaN";
--          length = 3;
--          break;
--        }
--        if( realvalue>0.0 ){
--          LONGDOUBLE_TYPE scale = 1.0;
--          while( realvalue>=1e100*scale && exp<=350 ){ scale *= 1e100;exp+=100;}
--          while( realvalue>=1e64*scale && exp<=350 ){ scale *= 1e64; exp+=64; }
--          while( realvalue>=1e8*scale && exp<=350 ){ scale *= 1e8; exp+=8; }
--          while( realvalue>=10.0*scale && exp<=350 ){ scale *= 10.0; exp++; }
--          realvalue /= scale;
--          while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; }
--          while( realvalue<1.0 ){ realvalue *= 10.0; exp--; }
--          if( exp>350 ){
--            if( prefix=='-' ){
--              bufpt = "-Inf";
--            }else if( prefix=='+' ){
--              bufpt = "+Inf";
--            }else{
--              bufpt = "Inf";
--            }
--            length = sqlite3Strlen30(bufpt);
--            break;
--          }
--        }
--        bufpt = buf;
--        /*
--        ** If the field type is etGENERIC, then convert to either etEXP
--        ** or etFLOAT, as appropriate.
--        */
--        if( xtype!=etFLOAT ){
--          realvalue += rounder;
--          if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }
--        }
--        if( xtype==etGENERIC ){
--          flag_rtz = !flag_alternateform;
--          if( exp<-4 || exp>precision ){
--            xtype = etEXP;
--          }else{
--            precision = precision - exp;
--            xtype = etFLOAT;
--          }
--        }else{
--          flag_rtz = flag_altform2;
--        }
--        if( xtype==etEXP ){
--          e2 = 0;
--        }else{
--          e2 = exp;
--        }
--        if( e2+precision+width > etBUFSIZE - 15 ){
--          bufpt = zExtra = sqlite3Malloc( e2+precision+width+15 );
--          if( bufpt==0 ){
--            pAccum->mallocFailed = 1;
--            return;
--          }
--        }
--        zOut = bufpt;
--        nsd = 16 + flag_altform2*10;
--        flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
--        /* The sign in front of the number */
--        if( prefix ){
--          *(bufpt++) = prefix;
--        }
--        /* Digits prior to the decimal point */
--        if( e2<0 ){
--          *(bufpt++) = '0';
--        }else{
--          for(; e2>=0; e2--){
--            *(bufpt++) = et_getdigit(&realvalue,&nsd);
--          }
--        }
--        /* The decimal point */
--        if( flag_dp ){
--          *(bufpt++) = '.';
--        }
--        /* "0" digits after the decimal point but before the first
--        ** significant digit of the number */
--        for(e2++; e2<0; precision--, e2++){
--          assert( precision>0 );
--          *(bufpt++) = '0';
--        }
--        /* Significant digits after the decimal point */
--        while( (precision--)>0 ){
--          *(bufpt++) = et_getdigit(&realvalue,&nsd);
--        }
--        /* Remove trailing zeros and the "." if no digits follow the "." */
--        if( flag_rtz && flag_dp ){
--          while( bufpt[-1]=='0' ) *(--bufpt) = 0;
--          assert( bufpt>zOut );
--          if( bufpt[-1]=='.' ){
--            if( flag_altform2 ){
--              *(bufpt++) = '0';
--            }else{
--              *(--bufpt) = 0;
--            }
--          }
--        }
--        /* Add the "eNNN" suffix */
--        if( xtype==etEXP ){
--          *(bufpt++) = aDigits[infop->charset];
--          if( exp<0 ){
--            *(bufpt++) = '-'; exp = -exp;
--          }else{
--            *(bufpt++) = '+';
--          }
--          if( exp>=100 ){
--            *(bufpt++) = (char)((exp/100)+'0');        /* 100's digit */
--            exp %= 100;
--          }
--          *(bufpt++) = (char)(exp/10+'0');             /* 10's digit */
--          *(bufpt++) = (char)(exp%10+'0');             /* 1's digit */
--        }
--        *bufpt = 0;
--
--        /* The converted number is in buf[] and zero terminated. Output it.
--        ** Note that the number is in the usual order, not reversed as with
--        ** integer conversions. */
--        length = (int)(bufpt-zOut);
--        bufpt = zOut;
--
--        /* Special case:  Add leading zeros if the flag_zeropad flag is
--        ** set and we are not left justified */
--        if( flag_zeropad && !flag_leftjustify && length < width){
--          int i;
--          int nPad = width - length;
--          for(i=width; i>=nPad; i--){
--            bufpt[i] = bufpt[i-nPad];
--          }
--          i = prefix!=0;
--          while( nPad-- ) bufpt[i++] = '0';
--          length = width;
--        }
--#endif /* !defined(SQLITE_OMIT_FLOATING_POINT) */
--        break;
--      case etSIZE:
--        *(va_arg(ap,int*)) = pAccum->nChar;
--        length = width = 0;
--        break;
--      case etPERCENT:
--        buf[0] = '%';
--        bufpt = buf;
--        length = 1;
--        break;
--      case etCHARX:
--        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;
--        }
--        bufpt = buf;
--        break;
--      case etSTRING:
--      case etDYNSTRING:
--        bufpt = va_arg(ap,char*);
--        if( bufpt==0 ){
--          bufpt = "";
--        }else if( xtype==etDYNSTRING ){
--          zExtra = bufpt;
--        }
--        if( precision>=0 ){
--          for(length=0; length<precision && bufpt[length]; length++){}
--        }else{
--          length = sqlite3Strlen30(bufpt);
--        }
--        break;
--      case etSQLESCAPE:
--      case etSQLESCAPE2:
--      case etSQLESCAPE3: {
--        int i, j, k, n, isnull;
--        int needQuote;
--        char ch;
--        char q = ((xtype==etSQLESCAPE3)?'"':'\'');   /* Quote character */
--        char *escarg = va_arg(ap,char*);
--        isnull = escarg==0;
--        if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
--        k = precision;
--        for(i=n=0; k!=0 && (ch=escarg[i])!=0; i++, k--){
--          if( ch==q )  n++;
--        }
--        needQuote = !isnull && xtype==etSQLESCAPE2;
--        n += i + 1 + needQuote*2;
--        if( n>etBUFSIZE ){
--          bufpt = zExtra = sqlite3Malloc( n );
--          if( bufpt==0 ){
--            pAccum->mallocFailed = 1;
--            return;
--          }
--        }else{
--          bufpt = buf;
--        }
--        j = 0;
--        if( needQuote ) bufpt[j++] = q;
--        k = i;
--        for(i=0; i<k; i++){
--          bufpt[j++] = ch = escarg[i];
--          if( ch==q ) bufpt[j++] = ch;
--        }
--        if( needQuote ) bufpt[j++] = q;
--        bufpt[j] = 0;
--        length = j;
--        /* The precision in %q and %Q means how many input characters to
--        ** consume, not the length of the output...
--        ** if( precision>=0 && precision<length ) length = precision; */
--        break;
--      }
--      case etTOKEN: {
--        Token *pToken = va_arg(ap, Token*);
--        if( pToken ){
--          sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n);
--        }
--        length = width = 0;
--        break;
--      }
--      case etSRCLIST: {
--        SrcList *pSrc = va_arg(ap, SrcList*);
--        int k = va_arg(ap, int);
--        struct SrcList_item *pItem = &pSrc->a[k];
--        assert( k>=0 && k<pSrc->nSrc );
--        if( pItem->zDatabase ){
--          sqlite3StrAccumAppend(pAccum, pItem->zDatabase, -1);
--          sqlite3StrAccumAppend(pAccum, ".", 1);
--        }
--        sqlite3StrAccumAppend(pAccum, pItem->zName, -1);
--        length = width = 0;
--        break;
--      }
--      default: {
--        assert( xtype==etINVALID );
--        return;
--      }
--    }/* End switch over the format type */
--    /*
--    ** The text of the conversion is pointed to by "bufpt" and is
--    ** "length" characters long.  The field width is "width".  Do
--    ** the output.
--    */
--    if( !flag_leftjustify ){
--      register int nspace;
--      nspace = width-length;
--      if( nspace>0 ){
--        sqlite3AppendSpace(pAccum, nspace);
--      }
--    }
--    if( length>0 ){
--      sqlite3StrAccumAppend(pAccum, bufpt, length);
--    }
--    if( flag_leftjustify ){
--      register int nspace;
--      nspace = width-length;
--      if( nspace>0 ){
--        sqlite3AppendSpace(pAccum, nspace);
--      }
--    }
--    sqlite3_free(zExtra);
--  }/* End for loop over the format string */
--} /* End of function */
-+    sqlite3_mutex_methods const *pFrom;
-+    sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex;
- 
--/*
--** Append N bytes of text from z to the StrAccum object.
--*/
--SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
--  assert( z!=0 || N==0 );
--  if( p->tooBig | p->mallocFailed ){
--    testcase(p->tooBig);
--    testcase(p->mallocFailed);
--    return;
--  }
--  assert( p->zText!=0 || p->nChar==0 );
--  if( N<0 ){
--    N = sqlite3Strlen30(z);
--  }
--  if( N==0 || NEVER(z==0) ){
--    return;
--  }
--  if( p->nChar+N >= p->nAlloc ){
--    char *zNew;
--    if( !p->useMalloc ){
--      p->tooBig = 1;
--      N = p->nAlloc - p->nChar - 1;
--      if( N<=0 ){
--        return;
--      }
-+    if( sqlite3GlobalConfig.bCoreMutex ){
-+      pFrom = sqlite3DefaultMutex();
-     }else{
--      char *zOld = (p->zText==p->zBase ? 0 : p->zText);
--      i64 szNew = p->nChar;
--      szNew += N + 1;
--      if( szNew > p->mxAlloc ){
--        sqlite3StrAccumReset(p);
--        p->tooBig = 1;
--        return;
--      }else{
--        p->nAlloc = (int)szNew;
--      }
--      if( p->useMalloc==1 ){
--        zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
--      }else{
--        zNew = sqlite3_realloc(zOld, p->nAlloc);
--      }
--      if( zNew ){
--        if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
--        p->zText = zNew;
--      }else{
--        p->mallocFailed = 1;
--        sqlite3StrAccumReset(p);
--        return;
--      }
-+      pFrom = sqlite3NoopMutex();
-     }
-+    memcpy(pTo, pFrom, offsetof(sqlite3_mutex_methods, xMutexAlloc));
-+    memcpy(&pTo->xMutexFree, &pFrom->xMutexFree,
-+           sizeof(*pTo) - offsetof(sqlite3_mutex_methods, xMutexFree));
-+    pTo->xMutexAlloc = pFrom->xMutexAlloc;
-   }
--  assert( p->zText );
--  memcpy(&p->zText[p->nChar], z, N);
--  p->nChar += N;
-+  rc = sqlite3GlobalConfig.mutex.xMutexInit();
-+
-+#ifdef SQLITE_DEBUG
-+  GLOBAL(int, mutexIsInit) = 1;
-+#endif
-+
-+  return rc;
- }
- 
- /*
--** Finish off a string by making sure it is zero-terminated.
--** Return a pointer to the resulting string.  Return a NULL
--** pointer if any kind of error was encountered.
-+** Shutdown the mutex system. This call frees resources allocated by
-+** sqlite3MutexInit().
- */
--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->zText ){
--        memcpy(p->zText, p->zBase, p->nChar+1);
--      }else{
--        p->mallocFailed = 1;
--      }
--    }
-+SQLITE_PRIVATE int sqlite3MutexEnd(void){
-+  int rc = SQLITE_OK;
-+  if( sqlite3GlobalConfig.mutex.xMutexEnd ){
-+    rc = sqlite3GlobalConfig.mutex.xMutexEnd();
-   }
--  return p->zText;
-+
-+#ifdef SQLITE_DEBUG
-+  GLOBAL(int, mutexIsInit) = 0;
-+#endif
-+
-+  return rc;
- }
- 
- /*
--** Reset an StrAccum string.  Reclaim all malloced memory.
-+** Retrieve a pointer to a static mutex or allocate a new dynamic one.
- */
--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);
--    }
--  }
--  p->zText = 0;
-+SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){
-+#ifndef SQLITE_OMIT_AUTOINIT
-+  if( sqlite3_initialize() ) return 0;
-+#endif
-+  return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
- }
- 
--/*
--** Initialize a string accumulator
--*/
--SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n, int mx){
--  p->zText = p->zBase = zBase;
--  p->db = 0;
--  p->nChar = 0;
--  p->nAlloc = n;
--  p->mxAlloc = mx;
--  p->useMalloc = 1;
--  p->tooBig = 0;
--  p->mallocFailed = 0;
-+SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){
-+  if( !sqlite3GlobalConfig.bCoreMutex ){
-+    return 0;
-+  }
-+  assert( GLOBAL(int, mutexIsInit) );
-+  return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
- }
- 
- /*
--** Print into memory obtained from sqliteMalloc().  Use the internal
--** %-conversion extensions.
-+** Free a dynamic mutex.
- */
--SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){
--  char *z;
--  char zBase[SQLITE_PRINT_BUF_SIZE];
--  StrAccum acc;
--  assert( db!=0 );
--  sqlite3StrAccumInit(&acc, zBase, sizeof(zBase),
--                      db->aLimit[SQLITE_LIMIT_LENGTH]);
--  acc.db = db;
--  sqlite3VXPrintf(&acc, 1, zFormat, ap);
--  z = sqlite3StrAccumFinish(&acc);
--  if( acc.mallocFailed ){
--    db->mallocFailed = 1;
-+SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *p){
-+  if( p ){
-+    sqlite3GlobalConfig.mutex.xMutexFree(p);
-   }
--  return z;
- }
- 
- /*
--** Print into memory obtained from sqliteMalloc().  Use the internal
--** %-conversion extensions.
-+** Obtain the mutex p. If some other thread already has the mutex, block
-+** until it can be obtained.
- */
--SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3 *db, const char *zFormat, ...){
--  va_list ap;
--  char *z;
--  va_start(ap, zFormat);
--  z = sqlite3VMPrintf(db, zFormat, ap);
--  va_end(ap);
--  return z;
-+SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex *p){
-+  if( p ){
-+    sqlite3GlobalConfig.mutex.xMutexEnter(p);
-+  }
- }
- 
- /*
--** Like sqlite3MPrintf(), but call sqlite3DbFree() on zStr after formatting
--** the string and before returnning.  This routine is intended to be used
--** to modify an existing string.  For example:
--**
--**       x = sqlite3MPrintf(db, x, "prefix %s suffix", x);
--**
-+** 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_PRIVATE char *sqlite3MAppendf(sqlite3 *db, char *zStr, const char *zFormat, ...){
--  va_list ap;
--  char *z;
--  va_start(ap, zFormat);
--  z = sqlite3VMPrintf(db, zFormat, ap);
--  va_end(ap);
--  sqlite3DbFree(db, zStr);
--  return z;
-+SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){
-+  int rc = SQLITE_OK;
-+  if( p ){
-+    return sqlite3GlobalConfig.mutex.xMutexTry(p);
-+  }
-+  return rc;
- }
- 
- /*
--** Print into memory obtained from sqlite3_malloc().  Omit the internal
--** %-conversion extensions.
-+** The sqlite3_mutex_leave() routine exits a mutex that was previously
-+** entered by the same thread.  The behavior is undefined if the mutex 
-+** is not currently entered. If a NULL pointer is passed as an argument
-+** this function is a no-op.
- */
--SQLITE_API char *sqlite3_vmprintf(const char *zFormat, va_list ap){
--  char *z;
--  char zBase[SQLITE_PRINT_BUF_SIZE];
--  StrAccum acc;
--#ifndef SQLITE_OMIT_AUTOINIT
--  if( sqlite3_initialize() ) return 0;
--#endif
--  sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
--  acc.useMalloc = 2;
--  sqlite3VXPrintf(&acc, 0, zFormat, ap);
--  z = sqlite3StrAccumFinish(&acc);
--  return z;
-+SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){
-+  if( p ){
-+    sqlite3GlobalConfig.mutex.xMutexLeave(p);
-+  }
- }
- 
-+#ifndef NDEBUG
- /*
--** Print into memory obtained from sqlite3_malloc()().  Omit the internal
--** %-conversion extensions.
-+** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
-+** intended for use inside assert() statements.
- */
--SQLITE_API char *sqlite3_mprintf(const char *zFormat, ...){
--  va_list ap;
--  char *z;
--#ifndef SQLITE_OMIT_AUTOINIT
--  if( sqlite3_initialize() ) return 0;
--#endif
--  va_start(ap, zFormat);
--  z = sqlite3_vmprintf(zFormat, ap);
--  va_end(ap);
--  return z;
-+SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){
-+  return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p);
- }
-+SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){
-+  return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
-+}
-+#endif
- 
-+#endif /* !defined(SQLITE_MUTEX_OMIT) */
-+
-+/************** End of mutex.c ***********************************************/
-+/************** Begin file mutex_noop.c **************************************/
- /*
--** sqlite3_snprintf() works like snprintf() except that it ignores the
--** current locale settings.  This is important for SQLite because we
--** are not able to use a "," as the decimal point in place of "." as
--** specified by some locales.
-+** 2008 October 07
- **
--** Oops:  The first two arguments of sqlite3_snprintf() are backwards
--** from the snprintf() standard.  Unfortunately, it is too late to change
--** this without breaking compatibility, so we just have to live with the
--** mistake.
-+** The author disclaims copyright to this source code.  In place of
-+** a legal notice, here is a blessing:
- **
--** sqlite3_vsnprintf() is the varargs version.
-+**    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 mutexes.
-+**
-+** This implementation in this file does not provide any mutual
-+** exclusion and is thus suitable for use only in applications
-+** that use SQLite in a single thread.  The routines defined
-+** here are place-holders.  Applications can substitute working
-+** mutex routines at start-time using the
-+**
-+**     sqlite3_config(SQLITE_CONFIG_MUTEX,...)
-+**
-+** interface.
-+**
-+** If compiled with SQLITE_DEBUG, then additional logic is inserted
-+** that does error checking on mutexes to make sure they are being
-+** called correctly.
- */
--SQLITE_API char *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;
--  sqlite3VXPrintf(&acc, 0, zFormat, ap);
--  return sqlite3StrAccumFinish(&acc);
--}
--SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
--  char *z;
--  va_list ap;
--  va_start(ap,zFormat);
--  z = sqlite3_vsnprintf(n, zBuf, zFormat, ap);
--  va_end(ap);
--  return z;
--}
- 
-+#ifndef SQLITE_MUTEX_OMIT
-+
-+#ifndef SQLITE_DEBUG
- /*
--** This is the routine that actually formats the sqlite3_log() message.
--** We house it in a separate routine from sqlite3_log() to avoid using
--** stack space on small-stack systems when logging is disabled.
-+** Stub routines for all mutex methods.
- **
--** sqlite3_log() must render into a static buffer.  It cannot dynamically
--** allocate memory because it might be called while the memory allocator
--** mutex is held.
-+** This routines provide no mutual exclusion or error checking.
- */
--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 */
-+static int noopMutexInit(void){ return SQLITE_OK; }
-+static int noopMutexEnd(void){ return SQLITE_OK; }
-+static sqlite3_mutex *noopMutexAlloc(int id){ 
-+  UNUSED_PARAMETER(id);
-+  return (sqlite3_mutex*)8; 
-+}
-+static void noopMutexFree(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; }
-+static void noopMutexEnter(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; }
-+static int noopMutexTry(sqlite3_mutex *p){
-+  UNUSED_PARAMETER(p);
-+  return SQLITE_OK;
-+}
-+static void noopMutexLeave(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; }
- 
--  sqlite3StrAccumInit(&acc, zMsg, sizeof(zMsg), 0);
--  acc.useMalloc = 0;
--  sqlite3VXPrintf(&acc, 0, zFormat, ap);
--  sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
--                           sqlite3StrAccumFinish(&acc));
-+SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void){
-+  static const sqlite3_mutex_methods sMutex = {
-+    noopMutexInit,
-+    noopMutexEnd,
-+    noopMutexAlloc,
-+    noopMutexFree,
-+    noopMutexEnter,
-+    noopMutexTry,
-+    noopMutexLeave,
-+
-+    0,
-+    0,
-+  };
-+
-+  return &sMutex;
- }
-+#endif /* !SQLITE_DEBUG */
- 
-+#ifdef SQLITE_DEBUG
- /*
--** Format and write a message to the log if logging is enabled.
-+** In this implementation, error checking is provided for testing
-+** and debugging purposes.  The mutexes still do not provide any
-+** mutual exclusion.
- */
--SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...){
--  va_list ap;                             /* Vararg list */
--  if( sqlite3GlobalConfig.xLog ){
--    va_start(ap, zFormat);
--    renderLogMsg(iErrCode, zFormat, ap);
--    va_end(ap);
--  }
--}
- 
--#if defined(SQLITE_DEBUG)
- /*
--** A version of printf() that understands %lld.  Used for debugging.
--** The printf() built into some versions of windows does not understand %lld
--** and segfaults if you give it a long long int.
-+** The mutex object
- */
--SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){
--  va_list ap;
--  StrAccum acc;
--  char zBuf[500];
--  sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0);
--  acc.useMalloc = 0;
--  va_start(ap,zFormat);
--  sqlite3VXPrintf(&acc, 0, zFormat, ap);
--  va_end(ap);
--  sqlite3StrAccumFinish(&acc);
--  fprintf(stdout,"%s", zBuf);
--  fflush(stdout);
--}
--#endif
-+typedef struct sqlite3_debug_mutex {
-+  int id;     /* The mutex type */
-+  int cnt;    /* Number of entries without a matching leave */
-+} sqlite3_debug_mutex;
- 
--#ifndef SQLITE_OMIT_TRACE
- /*
--** variable-argument wrapper around sqlite3VXPrintf().
-+** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
-+** intended for use inside assert() statements.
- */
--SQLITE_PRIVATE void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){
--  va_list ap;
--  va_start(ap,zFormat);
--  sqlite3VXPrintf(p, 1, zFormat, ap);
--  va_end(ap);
-+static int debugMutexHeld(sqlite3_mutex *pX){
-+  sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
-+  return p==0 || p->cnt>0;
-+}
-+static int debugMutexNotheld(sqlite3_mutex *pX){
-+  sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
-+  return p==0 || p->cnt==0;
- }
--#endif
- 
--/************** End of printf.c **********************************************/
--/************** Begin file random.c ******************************************/
- /*
--** 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 file contains code to implement a pseudo-random number
--** generator (PRNG) for SQLite.
--**
--** Random numbers are used by some of the database backends in order
--** to generate random integer keys for tables or random filenames.
--*/
--
--
--/* All threads share a single random number generator.
--** This structure is the current state of the generator.
-+** Initialize and deinitialize the mutex subsystem.
- */
--static SQLITE_WSD struct sqlite3PrngType {
--  unsigned char isInit;          /* True if initialized */
--  unsigned char i, j;            /* State variables */
--  unsigned char s[256];          /* State variables */
--} sqlite3Prng;
-+static int debugMutexInit(void){ return SQLITE_OK; }
-+static int debugMutexEnd(void){ return SQLITE_OK; }
- 
- /*
--** Get a single 8-bit random value from the RC4 PRNG.  The Mutex
--** must be held while executing this routine.
--**
--** Why not just use a library random generator like lrand48() for this?
--** Because the OP_NewRowid opcode in the VDBE depends on having a very
--** good source of random numbers.  The lrand48() library function may
--** well be good enough.  But maybe not.  Or maybe lrand48() has some
--** subtle problems on some systems that could cause problems.  It is hard
--** to know.  To minimize the risk of problems due to bad lrand48()
--** implementations, SQLite uses this random number generator based
--** on RC4, which we know works very well.
--**
--** (Later):  Actually, OP_NewRowid does not depend on a good source of
--** randomness any more.  But we will leave this code in all the same.
-+** 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. 
- */
--static u8 randomByte(void){
--  unsigned char t;
--
--
--  /* The "wsdPrng" macro will resolve to the pseudo-random number generator
--  ** 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, wsdPrng can refer directly
--  ** to the "sqlite3Prng" state vector declared above.
--  */
--#ifdef SQLITE_OMIT_WSD
--  struct sqlite3PrngType *p = &GLOBAL(struct sqlite3PrngType, sqlite3Prng);
--# define wsdPrng p[0]
--#else
--# define wsdPrng sqlite3Prng
--#endif
--
--
--  /* Initialize the state of the random number generator once,
--  ** the first time this routine is called.  The seed value does
--  ** not need to contain a lot of randomness since we are not
--  ** trying to do secure encryption or anything like that...
--  **
--  ** Nothing in this file or anywhere else in SQLite does any kind of
--  ** encryption.  The RC4 algorithm is being used as a PRNG (pseudo-random
--  ** number generator) not as an encryption device.
--  */
--  if( !wsdPrng.isInit ){
--    int i;
--    char k[256];
--    wsdPrng.j = 0;
--    wsdPrng.i = 0;
--    sqlite3OsRandomness(sqlite3_vfs_find(0), 256, k);
--    for(i=0; i<256; i++){
--      wsdPrng.s[i] = (u8)i;
-+static sqlite3_mutex *debugMutexAlloc(int id){
-+  static sqlite3_debug_mutex aStatic[6];
-+  sqlite3_debug_mutex *pNew = 0;
-+  switch( id ){
-+    case SQLITE_MUTEX_FAST:
-+    case SQLITE_MUTEX_RECURSIVE: {
-+      pNew = sqlite3Malloc(sizeof(*pNew));
-+      if( pNew ){
-+        pNew->id = id;
-+        pNew->cnt = 0;
-+      }
-+      break;
-     }
--    for(i=0; i<256; i++){
--      wsdPrng.j += wsdPrng.s[i] + k[i];
--      t = wsdPrng.s[wsdPrng.j];
--      wsdPrng.s[wsdPrng.j] = wsdPrng.s[i];
--      wsdPrng.s[i] = t;
-+    default: {
-+      assert( id-2 >= 0 );
-+      assert( id-2 < (int)(sizeof(aStatic)/sizeof(aStatic[0])) );
-+      pNew = &aStatic[id-2];
-+      pNew->id = id;
-+      break;
-     }
--    wsdPrng.isInit = 1;
-   }
-+  return (sqlite3_mutex*)pNew;
-+}
- 
--  /* Generate and return single random byte
--  */
--  wsdPrng.i++;
--  t = wsdPrng.s[wsdPrng.i];
--  wsdPrng.j += t;
--  wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j];
--  wsdPrng.s[wsdPrng.j] = t;
--  t += wsdPrng.s[wsdPrng.i];
--  return wsdPrng.s[t];
-+/*
-+** This routine deallocates a previously allocated mutex.
-+*/
-+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);
- }
- 
- /*
--** Return N random bytes.
-+** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
-+** to enter a mutex.  If another thread is already within the mutex,
-+** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
-+** 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,
-+** 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_API void sqlite3_randomness(int N, void *pBuf){
--  unsigned char *zBuf = pBuf;
--#if SQLITE_THREADSAFE
--  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
--#endif
--  sqlite3_mutex_enter(mutex);
--  while( N-- ){
--    *(zBuf++) = randomByte();
--  }
--  sqlite3_mutex_leave(mutex);
-+static void debugMutexEnter(sqlite3_mutex *pX){
-+  sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
-+  assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
-+  p->cnt++;
-+}
-+static int debugMutexTry(sqlite3_mutex *pX){
-+  sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
-+  assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
-+  p->cnt++;
-+  return SQLITE_OK;
- }
- 
--#ifndef SQLITE_OMIT_BUILTIN_TEST
- /*
--** For testing purposes, we sometimes want to preserve the state of
--** PRNG and restore the PRNG to its saved state at a later time, or
--** to reset the PRNG to its initial state.  These routines accomplish
--** those tasks.
--**
--** The sqlite3_test_control() interface calls these routines to
--** control the PRNG.
-+** The sqlite3_mutex_leave() routine exits a mutex that was
-+** previously entered by the same thread.  The behavior
-+** is undefined if the mutex is not currently entered or
-+** is not currently allocated.  SQLite will never do either.
- */
--static SQLITE_WSD struct sqlite3PrngType sqlite3SavedPrng;
--SQLITE_PRIVATE void sqlite3PrngSaveState(void){
--  memcpy(
--    &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng),
--    &GLOBAL(struct sqlite3PrngType, sqlite3Prng),
--    sizeof(sqlite3Prng)
--  );
-+static void debugMutexLeave(sqlite3_mutex *pX){
-+  sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
-+  assert( debugMutexHeld(pX) );
-+  p->cnt--;
-+  assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
- }
--SQLITE_PRIVATE void sqlite3PrngRestoreState(void){
--  memcpy(
--    &GLOBAL(struct sqlite3PrngType, sqlite3Prng),
--    &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng),
--    sizeof(sqlite3Prng)
--  );
-+
-+SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void){
-+  static const sqlite3_mutex_methods sMutex = {
-+    debugMutexInit,
-+    debugMutexEnd,
-+    debugMutexAlloc,
-+    debugMutexFree,
-+    debugMutexEnter,
-+    debugMutexTry,
-+    debugMutexLeave,
-+
-+    debugMutexHeld,
-+    debugMutexNotheld
-+  };
-+
-+  return &sMutex;
- }
--SQLITE_PRIVATE void sqlite3PrngResetState(void){
--  GLOBAL(struct sqlite3PrngType, sqlite3Prng).isInit = 0;
-+#endif /* SQLITE_DEBUG */
-+
-+/*
-+** If compiled with SQLITE_MUTEX_NOOP, then the no-op mutex implementation
-+** is used regardless of the run-time threadsafety setting.
-+*/
-+#ifdef SQLITE_MUTEX_NOOP
-+SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
-+  return sqlite3NoopMutex();
- }
--#endif /* SQLITE_OMIT_BUILTIN_TEST */
-+#endif /* defined(SQLITE_MUTEX_NOOP) */
-+#endif /* !defined(SQLITE_MUTEX_OMIT) */
- 
--/************** End of random.c **********************************************/
--/************** Begin file utf.c *********************************************/
-+/************** End of mutex_noop.c ******************************************/
-+/************** Begin file mutex_unix.c **************************************/
- /*
--** 2004 April 13
-+** 2007 August 28
- **
- ** The author disclaims copyright to this source code.  In place of
- ** a legal notice, here is a blessing:
-@@ -20682,2498 +21113,2601 @@
- **    May you share freely, never taking more than you give.
- **
- *************************************************************************
--** This file contains routines used to translate between UTF-8, 
--** UTF-16, UTF-16BE, and UTF-16LE.
--**
--** Notes on UTF-8:
--**
--**   Byte-0    Byte-1    Byte-2    Byte-3    Value
--**  0xxxxxxx                                 00000000 00000000 0xxxxxxx
--**  110yyyyy  10xxxxxx                       00000000 00000yyy yyxxxxxx
--**  1110zzzz  10yyyyyy  10xxxxxx             00000000 zzzzyyyy yyxxxxxx
--**  11110uuu  10uuzzzz  10yyyyyy  10xxxxxx   000uuuuu zzzzyyyy yyxxxxxx
--**
--**
--** Notes on UTF-16:  (with wwww+1==uuuuu)
--**
--**      Word-0               Word-1          Value
--**  110110ww wwzzzzyy   110111yy yyxxxxxx    000uuuuu zzzzyyyy yyxxxxxx
--**  zzzzyyyy yyxxxxxx                        00000000 zzzzyyyy yyxxxxxx
--**
--**
--** BOM or Byte Order Mark:
--**     0xff 0xfe   little-endian utf-16 follows
--**     0xfe 0xff   big-endian utf-16 follows
-+** This file contains the C functions that implement mutexes for pthreads
-+*/
-+
-+/*
-+** The code in this file is only used if we are compiling threadsafe
-+** under unix with pthreads.
- **
-+** Note that this implementation requires a version of pthreads that
-+** supports recursive mutexes.
- */
--/* #include <assert.h> */
-+#ifdef SQLITE_MUTEX_PTHREADS
-+
-+#include <pthread.h>
- 
--#ifndef SQLITE_AMALGAMATION
- /*
--** The following constant value is used by the SQLITE_BIGENDIAN and
--** SQLITE_LITTLEENDIAN macros.
-+** The sqlite3_mutex.id, sqlite3_mutex.nRef, and sqlite3_mutex.owner fields
-+** are necessary under two condidtions:  (1) Debug builds and (2) using
-+** home-grown mutexes.  Encapsulate these conditions into a single #define.
- */
--SQLITE_PRIVATE const int sqlite3one = 1;
--#endif /* SQLITE_AMALGAMATION */
-+#if defined(SQLITE_DEBUG) || defined(SQLITE_HOMEGROWN_RECURSIVE_MUTEX)
-+# define SQLITE_MUTEX_NREF 1
-+#else
-+# define SQLITE_MUTEX_NREF 0
-+#endif
- 
- /*
--** This lookup table is used to help decode the first byte of
--** a multi-byte UTF8 character.
-+** Each recursive mutex is an instance of the following structure.
- */
--static const unsigned char sqlite3Utf8Trans1[] = {
--  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
--  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
--  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
--  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
--  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
--  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
--  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
--  0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00,
-+struct sqlite3_mutex {
-+  pthread_mutex_t mutex;     /* Mutex controlling the lock */
-+#if SQLITE_MUTEX_NREF
-+  int id;                    /* Mutex type */
-+  volatile int nRef;         /* Number of entrances */
-+  volatile pthread_t owner;  /* Thread that is within this mutex */
-+  int trace;                 /* True to trace changes */
-+#endif
- };
-+#if SQLITE_MUTEX_NREF
-+#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0, (pthread_t)0, 0 }
-+#else
-+#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }
-+#endif
- 
--
--#define WRITE_UTF8(zOut, c) {                          \
--  if( c<0x00080 ){                                     \
--    *zOut++ = (u8)(c&0xFF);                            \
--  }                                                    \
--  else if( c<0x00800 ){                                \
--    *zOut++ = 0xC0 + (u8)((c>>6)&0x1F);                \
--    *zOut++ = 0x80 + (u8)(c & 0x3F);                   \
--  }                                                    \
--  else if( c<0x10000 ){                                \
--    *zOut++ = 0xE0 + (u8)((c>>12)&0x0F);               \
--    *zOut++ = 0x80 + (u8)((c>>6) & 0x3F);              \
--    *zOut++ = 0x80 + (u8)(c & 0x3F);                   \
--  }else{                                               \
--    *zOut++ = 0xF0 + (u8)((c>>18) & 0x07);             \
--    *zOut++ = 0x80 + (u8)((c>>12) & 0x3F);             \
--    *zOut++ = 0x80 + (u8)((c>>6) & 0x3F);              \
--    *zOut++ = 0x80 + (u8)(c & 0x3F);                   \
--  }                                                    \
--}
--
--#define WRITE_UTF16LE(zOut, c) {                                    \
--  if( c<=0xFFFF ){                                                  \
--    *zOut++ = (u8)(c&0x00FF);                                       \
--    *zOut++ = (u8)((c>>8)&0x00FF);                                  \
--  }else{                                                            \
--    *zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0));  \
--    *zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03));              \
--    *zOut++ = (u8)(c&0x00FF);                                       \
--    *zOut++ = (u8)(0x00DC + ((c>>8)&0x03));                         \
--  }                                                                 \
-+/*
-+** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
-+** intended for use only inside assert() statements.  On some platforms,
-+** there might be race conditions that can cause these routines to
-+** deliver incorrect results.  In particular, if pthread_equal() is
-+** not an atomic operation, then these routines might delivery
-+** incorrect results.  On most platforms, pthread_equal() is a 
-+** comparison of two integers and is therefore atomic.  But we are
-+** told that HPUX is not such a platform.  If so, then these routines
-+** will not always work correctly on HPUX.
-+**
-+** On those platforms where pthread_equal() is not atomic, SQLite
-+** should be compiled without -DSQLITE_DEBUG and with -DNDEBUG to
-+** make sure no assert() statements are evaluated and hence these
-+** routines are never called.
-+*/
-+#if !defined(NDEBUG) || defined(SQLITE_DEBUG)
-+static int pthreadMutexHeld(sqlite3_mutex *p){
-+  return (p->nRef!=0 && pthread_equal(p->owner, pthread_self()));
- }
--
--#define WRITE_UTF16BE(zOut, c) {                                    \
--  if( c<=0xFFFF ){                                                  \
--    *zOut++ = (u8)((c>>8)&0x00FF);                                  \
--    *zOut++ = (u8)(c&0x00FF);                                       \
--  }else{                                                            \
--    *zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03));              \
--    *zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0));  \
--    *zOut++ = (u8)(0x00DC + ((c>>8)&0x03));                         \
--    *zOut++ = (u8)(c&0x00FF);                                       \
--  }                                                                 \
-+static int pthreadMutexNotheld(sqlite3_mutex *p){
-+  return p->nRef==0 || pthread_equal(p->owner, pthread_self())==0;
- }
-+#endif
- 
--#define READ_UTF16LE(zIn, TERM, c){                                   \
--  c = (*zIn++);                                                       \
--  c += ((*zIn++)<<8);                                                 \
--  if( c>=0xD800 && c<0xE000 && TERM ){                                \
--    int c2 = (*zIn++);                                                \
--    c2 += ((*zIn++)<<8);                                              \
--    c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10);   \
--  }                                                                   \
--}
--
--#define READ_UTF16BE(zIn, TERM, c){                                   \
--  c = ((*zIn++)<<8);                                                  \
--  c += (*zIn++);                                                      \
--  if( c>=0xD800 && c<0xE000 && TERM ){                                \
--    int c2 = ((*zIn++)<<8);                                           \
--    c2 += (*zIn++);                                                   \
--    c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10);   \
--  }                                                                   \
--}
-+/*
-+** Initialize and deinitialize the mutex subsystem.
-+*/
-+static int pthreadMutexInit(void){ return SQLITE_OK; }
-+static int pthreadMutexEnd(void){ return SQLITE_OK; }
- 
- /*
--** Translate a single UTF-8 character.  Return the unicode value.
--**
--** During translation, assume that the byte that zTerm points
--** is a 0x00.
--**
--** Write a pointer to the next unread byte back into *pzNext.
--**
--** Notes On Invalid UTF-8:
-+** 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:
- **
--**  *  This routine never allows a 7-bit character (0x00 through 0x7f) to
--**     be encoded as a multi-byte character.  Any multi-byte character that
--**     attempts to encode a value between 0x00 and 0x7f is rendered as 0xfffd.
-+** <ul>
-+** <li>  SQLITE_MUTEX_FAST
-+** <li>  SQLITE_MUTEX_RECURSIVE
-+** <li>  SQLITE_MUTEX_STATIC_MASTER
-+** <li>  SQLITE_MUTEX_STATIC_MEM
-+** <li>  SQLITE_MUTEX_STATIC_MEM2
-+** <li>  SQLITE_MUTEX_STATIC_PRNG
-+** <li>  SQLITE_MUTEX_STATIC_LRU
-+** <li>  SQLITE_MUTEX_STATIC_PMEM
-+** </ul>
- **
--**  *  This routine never allows a UTF16 surrogate value to be encoded.
--**     If a multi-byte character attempts to encode a value between
--**     0xd800 and 0xe000 then it is rendered as 0xfffd.
-+** The first two constants cause sqlite3_mutex_alloc() to create
-+** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
-+** 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.  But 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.
- **
--**  *  Bytes in the range of 0x80 through 0xbf which occur as the first
--**     byte of a character are interpreted as single-byte characters
--**     and rendered as themselves even though they are technically
--**     invalid characters.
-+** The other allowed parameters to sqlite3_mutex_alloc() each return
-+** a pointer to a static preexisting mutex.  Six 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
-+** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
-+** SQLITE_MUTEX_RECURSIVE.
- **
--**  *  This routine accepts an infinite number of different UTF8 encodings
--**     for unicode values 0x80 and greater.  It do not change over-length
--**     encodings to 0xfffd as some systems recommend.
-+** 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 
-+** mutex types, the same mutex is returned on every call that has
-+** the same type number.
- */
--#define READ_UTF8(zIn, zTerm, c)                           \
--  c = *(zIn++);                                            \
--  if( c>=0xc0 ){                                           \
--    c = sqlite3Utf8Trans1[c-0xc0];                         \
--    while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){            \
--      c = (c<<6) + (0x3f & *(zIn++));                      \
--    }                                                      \
--    if( c<0x80                                             \
--        || (c&0xFFFFF800)==0xD800                          \
--        || (c&0xFFFFFFFE)==0xFFFE ){  c = 0xFFFD; }        \
--  }
--SQLITE_PRIVATE u32 sqlite3Utf8Read(
--  const unsigned char **pz    /* Pointer to string from which to read char */
--){
--  unsigned int c;
--
--  /* Same as READ_UTF8() above but without the zTerm parameter.
--  ** For this routine, we assume the UTF8 string is always zero-terminated.
--  */
--  c = *((*pz)++);
--  if( c>=0xc0 ){
--    c = sqlite3Utf8Trans1[c-0xc0];
--    while( (*(*pz) & 0xc0)==0x80 ){
--      c = (c<<6) + (0x3f & *((*pz)++));
-+static sqlite3_mutex *pthreadMutexAlloc(int iType){
-+  static sqlite3_mutex staticMutexes[] = {
-+    SQLITE3_MUTEX_INITIALIZER,
-+    SQLITE3_MUTEX_INITIALIZER,
-+    SQLITE3_MUTEX_INITIALIZER,
-+    SQLITE3_MUTEX_INITIALIZER,
-+    SQLITE3_MUTEX_INITIALIZER,
-+    SQLITE3_MUTEX_INITIALIZER
-+  };
-+  sqlite3_mutex *p;
-+  switch( iType ){
-+    case SQLITE_MUTEX_RECURSIVE: {
-+      p = sqlite3MallocZero( sizeof(*p) );
-+      if( p ){
-+#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
-+        /* If recursive mutexes are not available, we will have to
-+        ** build our own.  See below. */
-+        pthread_mutex_init(&p->mutex, 0);
-+#else
-+        /* Use a recursive mutex if it is available */
-+        pthread_mutexattr_t recursiveAttr;
-+        pthread_mutexattr_init(&recursiveAttr);
-+        pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE);
-+        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;
-+#endif
-+      break;
-     }
--    if( c<0x80
--        || (c&0xFFFFF800)==0xD800
--        || (c&0xFFFFFFFE)==0xFFFE ){  c = 0xFFFD; }
-   }
--  return c;
-+  return p;
- }
- 
- 
--
--
- /*
--** If the TRANSLATE_TRACE macro is defined, the value of each Mem is
--** printed on stderr on the way into and out of sqlite3VdbeMemTranslate().
--*/ 
--/* #define TRANSLATE_TRACE 1 */
-+** This routine deallocates a previously
-+** allocated mutex.  SQLite is careful to deallocate every
-+** mutex that it allocates.
-+*/
-+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);
-+}
- 
--#ifndef SQLITE_OMIT_UTF16
- /*
--** This routine transforms the internal text encoding used by pMem to
--** desiredEnc. It is an error if the string is already of the desired
--** encoding, or if *pMem does not contain a string value.
-+** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
-+** to enter a mutex.  If another thread is already within the mutex,
-+** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
-+** 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,
-+** 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_PRIVATE 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 */
--  unsigned char *zTerm;                 /* End of input */
--  unsigned char *z;                     /* Output iterator */
--  unsigned int c;
--
--  assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
--  assert( pMem->flags&MEM_Str );
--  assert( pMem->enc!=desiredEnc );
--  assert( pMem->enc!=0 );
--  assert( pMem->n>=0 );
--
--#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
--  {
--    char zBuf[100];
--    sqlite3VdbeMemPrettyPrint(pMem, zBuf);
--    fprintf(stderr, "INPUT:  %s\n", zBuf);
--  }
--#endif
-+static void pthreadMutexEnter(sqlite3_mutex *p){
-+  assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) );
- 
--  /* If the translation is between UTF-16 little and big endian, then 
--  ** all that is required is to swap the byte order. This case is handled
--  ** differently from the others.
-+#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
-+  /* If recursive mutexes are not available, then we have to grow
-+  ** our own.  This implementation assumes that pthread_equal()
-+  ** is atomic - that it cannot be deceived into thinking self
-+  ** and p->owner are equal if p->owner changes between two values
-+  ** that are not equal to self while the comparison is taking place.
-+  ** This implementation also assumes a coherent cache - that 
-+  ** separate processes cannot read different values from the same
-+  ** address at the same time.  If either of these two conditions
-+  ** are not met, then the mutexes will fail and problems will result.
-   */
--  if( pMem->enc!=SQLITE_UTF8 && desiredEnc!=SQLITE_UTF8 ){
--    u8 temp;
--    int rc;
--    rc = sqlite3VdbeMemMakeWriteable(pMem);
--    if( rc!=SQLITE_OK ){
--      assert( rc==SQLITE_NOMEM );
--      return SQLITE_NOMEM;
--    }
--    zIn = (u8*)pMem->z;
--    zTerm = &zIn[pMem->n&~1];
--    while( zIn<zTerm ){
--      temp = *zIn;
--      *zIn = *(zIn+1);
--      zIn++;
--      *zIn++ = temp;
-+  {
-+    pthread_t self = pthread_self();
-+    if( p->nRef>0 && pthread_equal(p->owner, self) ){
-+      p->nRef++;
-+    }else{
-+      pthread_mutex_lock(&p->mutex);
-+      assert( p->nRef==0 );
-+      p->owner = self;
-+      p->nRef = 1;
-     }
--    pMem->enc = desiredEnc;
--    goto translate_out;
-   }
-+#else
-+  /* Use the built-in recursive mutexes if they are available.
-+  */
-+  pthread_mutex_lock(&p->mutex);
-+#if SQLITE_MUTEX_NREF
-+  assert( p->nRef>0 || p->owner==0 );
-+  p->owner = pthread_self();
-+  p->nRef++;
-+#endif
-+#endif
- 
--  /* Set len to the maximum number of bytes required in the output buffer. */
--  if( desiredEnc==SQLITE_UTF8 ){
--    /* When converting from UTF-16, the maximum growth results from
--    ** translating a 2-byte character to a 4-byte UTF-8 character.
--    ** A single byte is required for the output string
--    ** nul-terminator.
--    */
--    pMem->n &= ~1;
--    len = pMem->n * 2 + 1;
--  }else{
--    /* When converting from UTF-8 to UTF-16 the maximum growth is caused
--    ** when a 1-byte UTF-8 character is translated into a 2-byte UTF-16
--    ** character. Two bytes are required in the output buffer for the
--    ** nul-terminator.
--    */
--    len = pMem->n * 2 + 2;
-+#ifdef SQLITE_DEBUG
-+  if( p->trace ){
-+    printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
-   }
-+#endif
-+}
-+static int pthreadMutexTry(sqlite3_mutex *p){
-+  int rc;
-+  assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) );
- 
--  /* Set zIn to point at the start of the input buffer and zTerm to point 1
--  ** byte past the end.
--  **
--  ** Variable zOut is set to point at the output buffer, space obtained
--  ** from sqlite3_malloc().
-+#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
-+  /* If recursive mutexes are not available, then we have to grow
-+  ** our own.  This implementation assumes that pthread_equal()
-+  ** is atomic - that it cannot be deceived into thinking self
-+  ** and p->owner are equal if p->owner changes between two values
-+  ** that are not equal to self while the comparison is taking place.
-+  ** This implementation also assumes a coherent cache - that 
-+  ** separate processes cannot read different values from the same
-+  ** address at the same time.  If either of these two conditions
-+  ** are not met, then the mutexes will fail and problems will result.
-   */
--  zIn = (u8*)pMem->z;
--  zTerm = &zIn[pMem->n];
--  zOut = sqlite3DbMallocRaw(pMem->db, len);
--  if( !zOut ){
--    return SQLITE_NOMEM;
--  }
--  z = zOut;
--
--  if( pMem->enc==SQLITE_UTF8 ){
--    if( desiredEnc==SQLITE_UTF16LE ){
--      /* UTF-8 -> UTF-16 Little-endian */
--      while( zIn<zTerm ){
--        READ_UTF8(zIn, zTerm, c);
--        WRITE_UTF16LE(z, c);
--      }
-+  {
-+    pthread_t self = pthread_self();
-+    if( p->nRef>0 && pthread_equal(p->owner, self) ){
-+      p->nRef++;
-+      rc = SQLITE_OK;
-+    }else if( pthread_mutex_trylock(&p->mutex)==0 ){
-+      assert( p->nRef==0 );
-+      p->owner = self;
-+      p->nRef = 1;
-+      rc = SQLITE_OK;
-     }else{
--      assert( desiredEnc==SQLITE_UTF16BE );
--      /* UTF-8 -> UTF-16 Big-endian */
--      while( zIn<zTerm ){
--        READ_UTF8(zIn, zTerm, c);
--        WRITE_UTF16BE(z, c);
--      }
-+      rc = SQLITE_BUSY;
-     }
--    pMem->n = (int)(z - zOut);
--    *z++ = 0;
-+  }
-+#else
-+  /* Use the built-in recursive mutexes if they are available.
-+  */
-+  if( pthread_mutex_trylock(&p->mutex)==0 ){
-+#if SQLITE_MUTEX_NREF
-+    p->owner = pthread_self();
-+    p->nRef++;
-+#endif
-+    rc = SQLITE_OK;
-   }else{
--    assert( desiredEnc==SQLITE_UTF8 );
--    if( pMem->enc==SQLITE_UTF16LE ){
--      /* UTF-16 Little-endian -> UTF-8 */
--      while( zIn<zTerm ){
--        READ_UTF16LE(zIn, zIn<zTerm, c); 
--        WRITE_UTF8(z, c);
--      }
--    }else{
--      /* UTF-16 Big-endian -> UTF-8 */
--      while( zIn<zTerm ){
--        READ_UTF16BE(zIn, zIn<zTerm, c); 
--        WRITE_UTF8(z, c);
--      }
--    }
--    pMem->n = (int)(z - zOut);
-+    rc = SQLITE_BUSY;
-   }
--  *z = 0;
--  assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len );
--
--  sqlite3VdbeMemRelease(pMem);
--  pMem->flags &= ~(MEM_Static|MEM_Dyn|MEM_Ephem);
--  pMem->enc = desiredEnc;
--  pMem->flags |= (MEM_Term|MEM_Dyn);
--  pMem->z = (char*)zOut;
--  pMem->zMalloc = pMem->z;
-+#endif
- 
--translate_out:
--#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
--  {
--    char zBuf[100];
--    sqlite3VdbeMemPrettyPrint(pMem, zBuf);
--    fprintf(stderr, "OUTPUT: %s\n", zBuf);
-+#ifdef SQLITE_DEBUG
-+  if( rc==SQLITE_OK && p->trace ){
-+    printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
-   }
- #endif
--  return SQLITE_OK;
-+  return rc;
- }
- 
- /*
--** This routine checks for a byte-order mark at the beginning of the 
--** UTF-16 string stored in *pMem. If one is present, it is removed and
--** the encoding of the Mem adjusted. This routine does not do any
--** byte-swapping, it just sets Mem.enc appropriately.
--**
--** The allocation (static, dynamic etc.) and encoding of the Mem may be
--** changed by this function.
-+** The sqlite3_mutex_leave() routine exits a mutex that was
-+** previously entered by the same thread.  The behavior
-+** is undefined if the mutex is not currently entered or
-+** is not currently allocated.  SQLite will never do either.
- */
--SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem){
--  int rc = SQLITE_OK;
--  u8 bom = 0;
-+static void pthreadMutexLeave(sqlite3_mutex *p){
-+  assert( pthreadMutexHeld(p) );
-+#if SQLITE_MUTEX_NREF
-+  p->nRef--;
-+  if( p->nRef==0 ) p->owner = 0;
-+#endif
-+  assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
- 
--  assert( pMem->n>=0 );
--  if( pMem->n>1 ){
--    u8 b1 = *(u8 *)pMem->z;
--    u8 b2 = *(((u8 *)pMem->z) + 1);
--    if( b1==0xFE && b2==0xFF ){
--      bom = SQLITE_UTF16BE;
--    }
--    if( b1==0xFF && b2==0xFE ){
--      bom = SQLITE_UTF16LE;
--    }
-+#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
-+  if( p->nRef==0 ){
-+    pthread_mutex_unlock(&p->mutex);
-   }
--  
--  if( bom ){
--    rc = sqlite3VdbeMemMakeWriteable(pMem);
--    if( rc==SQLITE_OK ){
--      pMem->n -= 2;
--      memmove(pMem->z, &pMem->z[2], pMem->n);
--      pMem->z[pMem->n] = '\0';
--      pMem->z[pMem->n+1] = '\0';
--      pMem->flags |= MEM_Term;
--      pMem->enc = bom;
--    }
-+#else
-+  pthread_mutex_unlock(&p->mutex);
-+#endif
-+
-+#ifdef SQLITE_DEBUG
-+  if( p->trace ){
-+    printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
-   }
--  return rc;
-+#endif
- }
--#endif /* SQLITE_OMIT_UTF16 */
- 
--/*
--** pZ is a UTF-8 encoded unicode string. If nByte is less than zero,
--** return the number of unicode characters in pZ up to (but not including)
--** the first 0x00 byte. If nByte is not less than zero, return the
--** number of unicode characters in the first nByte of pZ (or up to 
--** the first 0x00, whichever comes first).
--*/
--SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *zIn, int nByte){
--  int r = 0;
--  const u8 *z = (const u8*)zIn;
--  const u8 *zTerm;
--  if( nByte>=0 ){
--    zTerm = &z[nByte];
--  }else{
--    zTerm = (const u8*)(-1);
--  }
--  assert( z<=zTerm );
--  while( *z!=0 && z<zTerm ){
--    SQLITE_SKIP_UTF8(z);
--    r++;
--  }
--  return r;
-+SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
-+  static const sqlite3_mutex_methods sMutex = {
-+    pthreadMutexInit,
-+    pthreadMutexEnd,
-+    pthreadMutexAlloc,
-+    pthreadMutexFree,
-+    pthreadMutexEnter,
-+    pthreadMutexTry,
-+    pthreadMutexLeave,
-+#ifdef SQLITE_DEBUG
-+    pthreadMutexHeld,
-+    pthreadMutexNotheld
-+#else
-+    0,
-+    0
-+#endif
-+  };
-+
-+  return &sMutex;
- }
- 
--/* This test function is not currently used by the automated test-suite. 
--** Hence it is only available in debug builds.
--*/
--#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
-+#endif /* SQLITE_MUTEX_PTHREADS */
-+
-+/************** End of mutex_unix.c ******************************************/
-+/************** Begin file mutex_w32.c ***************************************/
- /*
--** Translate UTF-8 to UTF-8.
-+** 2007 August 14
- **
--** This has the effect of making sure that the string is well-formed
--** UTF-8.  Miscoded characters are removed.
-+** The author disclaims copyright to this source code.  In place of
-+** a legal notice, here is a blessing:
- **
--** The translation is done in-place and aborted if the output
--** overruns the input.
-+**    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 mutexes for win32
- */
--SQLITE_PRIVATE int sqlite3Utf8To8(unsigned char *zIn){
--  unsigned char *zOut = zIn;
--  unsigned char *zStart = zIn;
--  u32 c;
--
--  while( zIn[0] && zOut<=zIn ){
--    c = sqlite3Utf8Read((const u8**)&zIn);
--    if( c!=0xfffd ){
--      WRITE_UTF8(zOut, c);
--    }
--  }
--  *zOut = 0;
--  return (int)(zOut - zStart);
--}
--#endif
- 
--#ifndef SQLITE_OMIT_UTF16
- /*
--** Convert a UTF-16 string in the native encoding into a UTF-8 string.
--** Memory to hold the UTF-8 string is obtained from sqlite3_malloc and must
--** be freed by the calling function.
-+** The code in this file is only used if we are compiling multithreaded
-+** on a win32 system.
-+*/
-+#ifdef SQLITE_MUTEX_W32
-+
-+/*
-+** Each recursive mutex is an instance of the following structure.
-+*/
-+struct sqlite3_mutex {
-+  CRITICAL_SECTION mutex;    /* Mutex controlling the lock */
-+  int id;                    /* Mutex type */
-+#ifdef SQLITE_DEBUG
-+  volatile int nRef;         /* Number of enterances */
-+  volatile DWORD owner;      /* Thread holding this mutex */
-+  int trace;                 /* True to trace changes */
-+#endif
-+};
-+#define SQLITE_W32_MUTEX_INITIALIZER { 0 }
-+#ifdef SQLITE_DEBUG
-+#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, 0L, (DWORD)0, 0 }
-+#else
-+#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 }
-+#endif
-+
-+/*
-+** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
-+** or WinCE.  Return false (zero) for Win95, Win98, or WinME.
- **
--** NULL is returned if there is an allocation error.
-+** 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 win 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.
-+**
-+** mutexIsNT() is only used for the TryEnterCriticalSection() API call,
-+** which is only available if your application was compiled with 
-+** _WIN32_WINNT defined to a value >= 0x0400.  Currently, the only
-+** call to TryEnterCriticalSection() is #ifdef'ed out, so #ifdef 
-+** this out as well.
- */
--SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *db, const void *z, int nByte, u8 enc){
--  Mem m;
--  memset(&m, 0, sizeof(m));
--  m.db = db;
--  sqlite3VdbeMemSetStr(&m, z, nByte, enc, SQLITE_STATIC);
--  sqlite3VdbeChangeEncoding(&m, SQLITE_UTF8);
--  if( db->mallocFailed ){
--    sqlite3VdbeMemRelease(&m);
--    m.z = 0;
-+#if 0
-+#if SQLITE_OS_WINCE || SQLITE_OS_WINRT
-+# define mutexIsNT()  (1)
-+#else
-+  static int mutexIsNT(void){
-+    static int osType = 0;
-+    if( osType==0 ){
-+      OSVERSIONINFO sInfo;
-+      sInfo.dwOSVersionInfoSize = sizeof(sInfo);
-+      GetVersionEx(&sInfo);
-+      osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
-+    }
-+    return osType==2;
-   }
--  assert( (m.flags & MEM_Term)!=0 || db->mallocFailed );
--  assert( (m.flags & MEM_Str)!=0 || db->mallocFailed );
--  assert( (m.flags & MEM_Dyn)!=0 || db->mallocFailed );
--  assert( m.z || db->mallocFailed );
--  return m.z;
--}
-+#endif /* SQLITE_OS_WINCE */
-+#endif
- 
-+#ifdef SQLITE_DEBUG
- /*
--** Convert a UTF-8 string to the UTF-16 encoding specified by parameter
--** enc. A pointer to the new string is returned, and the value of *pnOut
--** is set to the length of the returned string in bytes. The call should
--** arrange to call sqlite3DbFree() on the returned pointer when it is
--** no longer required.
--** 
--** If a malloc failure occurs, NULL is returned and the db.mallocFailed
--** flag set.
-+** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
-+** intended for use only inside assert() statements.
- */
--#ifdef SQLITE_ENABLE_STAT3
--SQLITE_PRIVATE char *sqlite3Utf8to16(sqlite3 *db, u8 enc, char *z, int n, int *pnOut){
--  Mem m;
--  memset(&m, 0, sizeof(m));
--  m.db = db;
--  sqlite3VdbeMemSetStr(&m, z, n, SQLITE_UTF8, SQLITE_STATIC);
--  if( sqlite3VdbeMemTranslate(&m, enc) ){
--    assert( db->mallocFailed );
--    return 0;
--  }
--  assert( m.z==m.zMalloc );
--  *pnOut = m.n;
--  return m.z;
-+static int winMutexHeld(sqlite3_mutex *p){
-+  return p->nRef!=0 && p->owner==GetCurrentThreadId();
-+}
-+static int winMutexNotheld2(sqlite3_mutex *p, DWORD tid){
-+  return p->nRef==0 || p->owner!=tid;
-+}
-+static int winMutexNotheld(sqlite3_mutex *p){
-+  DWORD tid = GetCurrentThreadId(); 
-+  return winMutexNotheld2(p, tid);
- }
- #endif
- 
-+
- /*
--** zIn is a UTF-16 encoded unicode string at least nChar characters long.
--** Return the number of bytes in the first nChar unicode characters
--** in pZ.  nChar must be non-negative.
-+** Initialize and deinitialize the mutex subsystem.
- */
--SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *zIn, int nChar){
--  int c;
--  unsigned char const *z = zIn;
--  int n = 0;
--  
--  if( SQLITE_UTF16NATIVE==SQLITE_UTF16BE ){
--    while( n<nChar ){
--      READ_UTF16BE(z, 1, c);
--      n++;
-+static sqlite3_mutex winMutex_staticMutexes[6] = {
-+  SQLITE3_MUTEX_INITIALIZER,
-+  SQLITE3_MUTEX_INITIALIZER,
-+  SQLITE3_MUTEX_INITIALIZER,
-+  SQLITE3_MUTEX_INITIALIZER,
-+  SQLITE3_MUTEX_INITIALIZER,
-+  SQLITE3_MUTEX_INITIALIZER
-+};
-+static int winMutex_isInit = 0;
-+/* As winMutexInit() and winMutexEnd() are called as part
-+** of the sqlite3_initialize and sqlite3_shutdown()
-+** processing, the "interlocked" magic is probably not
-+** strictly necessary.
-+*/
-+static long winMutex_lock = 0;
-+
-+SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
-+
-+static int winMutexInit(void){ 
-+  /* The first to increment to 1 does actual initialization */
-+  if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){
-+    int i;
-+    for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
-+#if SQLITE_OS_WINRT
-+      InitializeCriticalSectionEx(&winMutex_staticMutexes[i].mutex, 0, 0);
-+#else
-+      InitializeCriticalSection(&winMutex_staticMutexes[i].mutex);
-+#endif
-     }
-+    winMutex_isInit = 1;
-   }else{
--    while( n<nChar ){
--      READ_UTF16LE(z, 1, c);
--      n++;
-+    /* Someone else is in the process of initing the static mutexes */
-+    while( !winMutex_isInit ){
-+      sqlite3_win32_sleep(1);
-     }
-   }
--  return (int)(z-(unsigned char const *)zIn);
-+  return SQLITE_OK; 
- }
- 
--#if defined(SQLITE_TEST)
--/*
--** This routine is called from the TCL test function "translate_selftest".
--** It checks that the primitives for serializing and deserializing
--** characters in each encoding are inverses of each other.
--*/
--SQLITE_PRIVATE void sqlite3UtfSelfTest(void){
--  unsigned int i, t;
--  unsigned char zBuf[20];
--  unsigned char *z;
--  int n;
--  unsigned int c;
--
--  for(i=0; i<0x00110000; i++){
--    z = zBuf;
--    WRITE_UTF8(z, i);
--    n = (int)(z-zBuf);
--    assert( n>0 && n<=4 );
--    z[0] = 0;
--    z = zBuf;
--    c = sqlite3Utf8Read((const u8**)&z);
--    t = i;
--    if( i>=0xD800 && i<=0xDFFF ) t = 0xFFFD;
--    if( (i&0xFFFFFFFE)==0xFFFE ) t = 0xFFFD;
--    assert( c==t );
--    assert( (z-zBuf)==n );
--  }
--  for(i=0; i<0x00110000; i++){
--    if( i>=0xD800 && i<0xE000 ) continue;
--    z = zBuf;
--    WRITE_UTF16LE(z, i);
--    n = (int)(z-zBuf);
--    assert( n>0 && n<=4 );
--    z[0] = 0;
--    z = zBuf;
--    READ_UTF16LE(z, 1, c);
--    assert( c==i );
--    assert( (z-zBuf)==n );
--  }
--  for(i=0; i<0x00110000; i++){
--    if( i>=0xD800 && i<0xE000 ) continue;
--    z = zBuf;
--    WRITE_UTF16BE(z, i);
--    n = (int)(z-zBuf);
--    assert( n>0 && n<=4 );
--    z[0] = 0;
--    z = zBuf;
--    READ_UTF16BE(z, 1, c);
--    assert( c==i );
--    assert( (z-zBuf)==n );
-+static int winMutexEnd(void){ 
-+  /* The first to decrement to 0 does actual shutdown 
-+  ** (which should be the last to shutdown.) */
-+  if( InterlockedCompareExchange(&winMutex_lock, 0, 1)==1 ){
-+    if( winMutex_isInit==1 ){
-+      int i;
-+      for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
-+        DeleteCriticalSection(&winMutex_staticMutexes[i].mutex);
-+      }
-+      winMutex_isInit = 0;
-+    }
-   }
-+  return SQLITE_OK; 
- }
--#endif /* SQLITE_TEST */
--#endif /* SQLITE_OMIT_UTF16 */
- 
--/************** End of utf.c *************************************************/
--/************** Begin file util.c ********************************************/
- /*
--** 2001 September 15
--**
--** The author disclaims copyright to this source code.  In place of
--** a legal notice, here is a blessing:
-+** 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:
- **
--**    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.
-+** <ul>
-+** <li>  SQLITE_MUTEX_FAST
-+** <li>  SQLITE_MUTEX_RECURSIVE
-+** <li>  SQLITE_MUTEX_STATIC_MASTER
-+** <li>  SQLITE_MUTEX_STATIC_MEM
-+** <li>  SQLITE_MUTEX_STATIC_MEM2
-+** <li>  SQLITE_MUTEX_STATIC_PRNG
-+** <li>  SQLITE_MUTEX_STATIC_LRU
-+** <li>  SQLITE_MUTEX_STATIC_PMEM
-+** </ul>
- **
--*************************************************************************
--** Utility functions used throughout sqlite.
-+** The first two constants cause sqlite3_mutex_alloc() to create
-+** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
-+** 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.  But 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.
- **
--** This file contains functions for allocating memory, comparing
--** strings, and stuff like that.
-+** The other allowed parameters to sqlite3_mutex_alloc() each return
-+** a pointer to a static preexisting mutex.  Six 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
-+** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
-+** SQLITE_MUTEX_RECURSIVE.
- **
-+** 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 
-+** mutex types, the same mutex is returned on every call that has
-+** the same type number.
- */
--/* #include <stdarg.h> */
--#ifdef SQLITE_HAVE_ISNAN
--# include <math.h>
-+static sqlite3_mutex *winMutexAlloc(int iType){
-+  sqlite3_mutex *p;
-+
-+  switch( iType ){
-+    case SQLITE_MUTEX_FAST:
-+    case SQLITE_MUTEX_RECURSIVE: {
-+      p = sqlite3MallocZero( sizeof(*p) );
-+      if( p ){  
-+#ifdef SQLITE_DEBUG
-+        p->id = iType;
-+#endif
-+#if SQLITE_OS_WINRT
-+        InitializeCriticalSectionEx(&p->mutex, 0, 0);
-+#else
-+        InitializeCriticalSection(&p->mutex);
-+#endif
-+      }
-+      break;
-+    }
-+    default: {
-+      assert( winMutex_isInit==1 );
-+      assert( iType-2 >= 0 );
-+      assert( iType-2 < ArraySize(winMutex_staticMutexes) );
-+      p = &winMutex_staticMutexes[iType-2];
-+#ifdef SQLITE_DEBUG
-+      p->id = iType;
- #endif
-+      break;
-+    }
-+  }
-+  return p;
-+}
-+
- 
- /*
--** Routine needed to support the testcase() macro.
-+** This routine deallocates a previously
-+** allocated mutex.  SQLite is careful to deallocate every
-+** mutex that it allocates.
- */
--#ifdef SQLITE_COVERAGE_TEST
--SQLITE_PRIVATE void sqlite3Coverage(int x){
--  static unsigned dummy = 0;
--  dummy += (unsigned)x;
-+static void winMutexFree(sqlite3_mutex *p){
-+  assert( p );
-+  assert( p->nRef==0 && p->owner==0 );
-+  assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
-+  DeleteCriticalSection(&p->mutex);
-+  sqlite3_free(p);
- }
--#endif
- 
--#ifndef SQLITE_OMIT_FLOATING_POINT
- /*
--** Return true if the floating point value is Not a Number (NaN).
--**
--** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN.
--** Otherwise, we have our own implementation that works on most systems.
-+** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
-+** to enter a mutex.  If another thread is already within the mutex,
-+** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
-+** 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,
-+** 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_PRIVATE int sqlite3IsNaN(double x){
--  int rc;   /* The value return */
--#if !defined(SQLITE_HAVE_ISNAN)
-+static void winMutexEnter(sqlite3_mutex *p){
-+#ifdef SQLITE_DEBUG
-+  DWORD tid = GetCurrentThreadId(); 
-+  assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) );
-+#endif
-+  EnterCriticalSection(&p->mutex);
-+#ifdef SQLITE_DEBUG
-+  assert( p->nRef>0 || p->owner==0 );
-+  p->owner = tid; 
-+  p->nRef++;
-+  if( p->trace ){
-+    printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
-+  }
-+#endif
-+}
-+static int winMutexTry(sqlite3_mutex *p){
-+#ifndef NDEBUG
-+  DWORD tid = GetCurrentThreadId(); 
-+#endif
-+  int rc = SQLITE_BUSY;
-+  assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) );
-   /*
--  ** Systems that support the isnan() library function should probably
--  ** make use of it by compiling with -DSQLITE_HAVE_ISNAN.  But we have
--  ** found that many systems do not have a working isnan() function so
--  ** this implementation is provided as an alternative.
--  **
--  ** This NaN test sometimes fails if compiled on GCC with -ffast-math.
--  ** On the other hand, the use of -ffast-math comes with the following
--  ** warning:
--  **
--  **      This option [-ffast-math] should never be turned on by any
--  **      -O option since it can result in incorrect output for programs
--  **      which depend on an exact implementation of IEEE or ISO 
--  **      rules/specifications for math functions.
--  **
--  ** Under MSVC, this NaN test may fail if compiled with a floating-
--  ** point precision mode other than /fp:precise.  From the MSDN 
--  ** documentation:
-+  ** The sqlite3_mutex_try() routine is very rarely used, and when it
-+  ** is used it is merely an optimization.  So it is OK for it to always
-+  ** fail.  
-   **
--  **      The compiler [with /fp:precise] will properly handle comparisons 
--  **      involving NaN. For example, x != x evaluates to true if x is NaN 
--  **      ...
-+  ** The TryEnterCriticalSection() interface is only available on WinNT.
-+  ** And some windows compilers complain if you try to use it without
-+  ** first doing some #defines that prevent SQLite from building on Win98.
-+  ** For that reason, we will omit this optimization for now.  See
-+  ** ticket #2685.
-   */
--#ifdef __FAST_MATH__
--# error SQLite will not work correctly with the -ffast-math option of GCC.
-+#if 0
-+  if( mutexIsNT() && TryEnterCriticalSection(&p->mutex) ){
-+    p->owner = tid;
-+    p->nRef++;
-+    rc = SQLITE_OK;
-+  }
-+#else
-+  UNUSED_PARAMETER(p);
-+#endif
-+#ifdef SQLITE_DEBUG
-+  if( rc==SQLITE_OK && p->trace ){
-+    printf("try mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
-+  }
- #endif
--  volatile double y = x;
--  volatile double z = y;
--  rc = (y!=z);
--#else  /* if defined(SQLITE_HAVE_ISNAN) */
--  rc = isnan(x);
--#endif /* SQLITE_HAVE_ISNAN */
--  testcase( rc );
-   return rc;
- }
--#endif /* SQLITE_OMIT_FLOATING_POINT */
- 
- /*
--** Compute a string length that is limited to what can be stored in
--** lower 30 bits of a 32-bit signed integer.
--**
--** The value returned will never be negative.  Nor will it ever be greater
--** than the actual length of the string.  For very long strings (greater
--** than 1GiB) the value returned might be less than the true string length.
-+** The sqlite3_mutex_leave() routine exits a mutex that was
-+** previously entered by the same thread.  The behavior
-+** is undefined if the mutex is not currently entered or
-+** is not currently allocated.  SQLite will never do either.
- */
--SQLITE_PRIVATE int sqlite3Strlen30(const char *z){
--  const char *z2 = z;
--  if( z==0 ) return 0;
--  while( *z2 ){ z2++; }
--  return 0x3fffffff & (int)(z2 - z);
-+static void winMutexLeave(sqlite3_mutex *p){
-+#ifndef NDEBUG
-+  DWORD tid = GetCurrentThreadId();
-+  assert( p->nRef>0 );
-+  assert( p->owner==tid );
-+  p->nRef--;
-+  if( p->nRef==0 ) p->owner = 0;
-+  assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
-+#endif
-+  LeaveCriticalSection(&p->mutex);
-+#ifdef SQLITE_DEBUG
-+  if( p->trace ){
-+    printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
-+  }
-+#endif
-+}
-+
-+SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
-+  static const sqlite3_mutex_methods sMutex = {
-+    winMutexInit,
-+    winMutexEnd,
-+    winMutexAlloc,
-+    winMutexFree,
-+    winMutexEnter,
-+    winMutexTry,
-+    winMutexLeave,
-+#ifdef SQLITE_DEBUG
-+    winMutexHeld,
-+    winMutexNotheld
-+#else
-+    0,
-+    0
-+#endif
-+  };
-+
-+  return &sMutex;
- }
-+#endif /* SQLITE_MUTEX_W32 */
- 
-+/************** End of mutex_w32.c *******************************************/
-+/************** Begin file malloc.c ******************************************/
- /*
--** Set the most recent error code and error string for the sqlite
--** handle "db". The error code is set to "err_code".
-+** 2001 September 15
- **
--** If it is not NULL, string zFormat specifies the format of the
--** error string in the style of the printf functions: The following
--** format characters are allowed:
-+** The author disclaims copyright to this source code.  In place of
-+** a legal notice, here is a blessing:
- **
--**      %s      Insert a string
--**      %z      A string that should be freed after use
--**      %d      Insert an integer
--**      %T      Insert a token
--**      %S      Insert the first element of a SrcList
-+**    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.
- **
--** zFormat and any string tokens that follow it are assumed to be
--** encoded in UTF-8.
-+*************************************************************************
- **
--** To clear the most recent error for sqlite handle "db", sqlite3Error
--** should be called with err_code set to SQLITE_OK and zFormat set
--** to NULL.
-+** Memory allocation functions used throughout sqlite.
- */
--SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat, ...){
--  if( db && (db->pErr || (db->pErr = sqlite3ValueNew(db))!=0) ){
--    db->errCode = err_code;
--    if( zFormat ){
--      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{
--      sqlite3ValueSetStr(db->pErr, 0, 0, SQLITE_UTF8, SQLITE_STATIC);
--    }
--  }
--}
-+/* #include <stdarg.h> */
- 
- /*
--** Add an error message to pParse->zErrMsg and increment pParse->nErr.
--** The following formatting characters are allowed:
--**
--**      %s      Insert a string
--**      %z      A string that should be freed after use
--**      %d      Insert an integer
--**      %T      Insert a token
--**      %S      Insert the first element of a SrcList
--**
--** This function should be used to report any error that occurs whilst
--** 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.).
-+** Attempt to release up to n bytes of non-essential memory currently
-+** held by SQLite. An example of non-essential memory is memory used to
-+** cache database pages that are not currently in use.
- */
--SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
--  char *zMsg;
--  va_list ap;
--  sqlite3 *db = pParse->db;
--  va_start(ap, zFormat);
--  zMsg = sqlite3VMPrintf(db, zFormat, ap);
--  va_end(ap);
--  if( db->suppressErr ){
--    sqlite3DbFree(db, zMsg);
--  }else{
--    pParse->nErr++;
--    sqlite3DbFree(db, pParse->zErrMsg);
--    pParse->zErrMsg = zMsg;
--    pParse->rc = SQLITE_ERROR;
--  }
-+SQLITE_API int sqlite3_release_memory(int n){
-+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
-+  return sqlite3PcacheReleaseMemory(n);
-+#else
-+  /* IMPLEMENTATION-OF: R-34391-24921 The sqlite3_release_memory() routine
-+  ** is a no-op returning zero if SQLite is not compiled with
-+  ** SQLITE_ENABLE_MEMORY_MANAGEMENT. */
-+  UNUSED_PARAMETER(n);
-+  return 0;
-+#endif
- }
- 
- /*
--** Convert an SQL-style quoted string into a normal string by removing
--** the quote characters.  The conversion is done in-place.  If the
--** input does not begin with a quote character, then this routine
--** is a no-op.
--**
--** The input string must be zero-terminated.  A new zero-terminator
--** is added to the dequoted string.
--**
--** The return value is -1 if no dequoting occurs or the length of the
--** dequoted string, exclusive of the zero terminator, if dequoting does
--** occur.
--**
--** 2002-Feb-14: This routine is extended to remove MS-Access style
--** brackets from around identifers.  For example:  "[a-b-c]" becomes
--** "a-b-c".
-+** An instance of the following object records the location of
-+** each unused scratch buffer.
- */
--SQLITE_PRIVATE int sqlite3Dequote(char *z){
--  char quote;
--  int i, j;
--  if( z==0 ) return -1;
--  quote = z[0];
--  switch( quote ){
--    case '\'':  break;
--    case '"':   break;
--    case '`':   break;                /* For MySQL compatibility */
--    case '[':   quote = ']';  break;  /* For MS SqlServer compatibility */
--    default:    return -1;
--  }
--  for(i=1, j=0; ALWAYS(z[i]); i++){
--    if( z[i]==quote ){
--      if( z[i+1]==quote ){
--        z[j++] = quote;
--        i++;
--      }else{
--        break;
--      }
--    }else{
--      z[j++] = z[i];
--    }
--  }
--  z[j] = 0;
--  return j;
--}
-+typedef struct ScratchFreeslot {
-+  struct ScratchFreeslot *pNext;   /* Next unused scratch buffer */
-+} ScratchFreeslot;
- 
--/* Convenient short-hand */
--#define UpperToLower sqlite3UpperToLower
-+/*
-+** State information local to the memory allocation subsystem.
-+*/
-+static SQLITE_WSD struct Mem0Global {
-+  sqlite3_mutex *mutex;         /* Mutex to serialize access */
-+
-+  /*
-+  ** The alarm callback and its arguments.  The mem0.mutex lock will
-+  ** be held while the callback is running.  Recursive calls into
-+  ** the memory subsystem are allowed, but no new callbacks will be
-+  ** issued.
-+  */
-+  sqlite3_int64 alarmThreshold;
-+  void (*alarmCallback)(void*, sqlite3_int64,int);
-+  void *alarmArg;
-+
-+  /*
-+  ** Pointers to the end of sqlite3GlobalConfig.pScratch memory
-+  ** (so that a range test can be used to determine if an allocation
-+  ** being freed came from pScratch) and a pointer to the list of
-+  ** unused scratch allocations.
-+  */
-+  void *pScratchEnd;
-+  ScratchFreeslot *pScratchFree;
-+  u32 nScratchFree;
-+
-+  /*
-+  ** True if heap is nearly "full" where "full" is defined by the
-+  ** sqlite3_soft_heap_limit() setting.
-+  */
-+  int nearlyFull;
-+} mem0 = { 0, 0, 0, 0, 0, 0, 0, 0 };
-+
-+#define mem0 GLOBAL(struct Mem0Global, mem0)
- 
- /*
--** Some systems have stricmp().  Others have strcasecmp().  Because
--** there is no consistency, we will define our own.
--**
--** IMPLEMENTATION-OF: R-30243-02494 The sqlite3_stricmp() and
--** sqlite3_strnicmp() APIs allow applications and extensions to compare
--** the contents of two buffers containing UTF-8 strings in a
--** case-independent fashion, using the same definition of "case
--** independence" that SQLite uses internally when comparing identifiers.
-+** This routine runs when the memory allocator sees that the
-+** total memory allocation is about to exceed the soft heap
-+** limit.
- */
--SQLITE_API int sqlite3_stricmp(const char *zLeft, const char *zRight){
--  register unsigned char *a, *b;
--  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){
--  register unsigned char *a, *b;
--  a = (unsigned char *)zLeft;
--  b = (unsigned char *)zRight;
--  while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
--  return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b];
-+static void softHeapLimitEnforcer(
-+  void *NotUsed, 
-+  sqlite3_int64 NotUsed2,
-+  int allocSize
-+){
-+  UNUSED_PARAMETER2(NotUsed, NotUsed2);
-+  sqlite3_release_memory(allocSize);
- }
- 
- /*
--** The string z[] is an text representation of a real number.
--** Convert this string to a double and write it into *pResult.
--**
--** The string z[] is length bytes in length (bytes, not characters) and
--** uses the encoding enc.  The string is not necessarily zero-terminated.
--**
--** Return TRUE if the result is a valid real number (or integer) and FALSE
--** if the string is empty or contains extraneous text.  Valid numbers
--** are in one of these formats:
--**
--**    [+-]digits[E[+-]digits]
--**    [+-]digits.[digits][E[+-]digits]
--**    [+-].digits[E[+-]digits]
--**
--** Leading and trailing whitespace is ignored for the purpose of determining
--** validity.
--**
--** If some prefix of the input string is a valid number, this routine
--** returns FALSE but it still converts the prefix and writes the result
--** into *pResult.
-+** Change the alarm callback
- */
--SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
--#ifndef SQLITE_OMIT_FLOATING_POINT
--  int incr;
--  const char *zEnd = z + length;
--  /* sign * significand * (10 ^ (esign * exponent)) */
--  int sign = 1;    /* sign of significand */
--  i64 s = 0;       /* significand */
--  int d = 0;       /* adjust exponent for shifting decimal point */
--  int esign = 1;   /* sign of exponent */
--  int e = 0;       /* exponent */
--  int eValid = 1;  /* True exponent is either not used or is well-formed */
--  double result;
--  int nDigits = 0;
--  int nonNum = 0;
-+static int sqlite3MemoryAlarm(
-+  void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
-+  void *pArg,
-+  sqlite3_int64 iThreshold
-+){
-+  int nUsed;
-+  sqlite3_mutex_enter(mem0.mutex);
-+  mem0.alarmCallback = xCallback;
-+  mem0.alarmArg = pArg;
-+  mem0.alarmThreshold = iThreshold;
-+  nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
-+  mem0.nearlyFull = (iThreshold>0 && iThreshold<=nUsed);
-+  sqlite3_mutex_leave(mem0.mutex);
-+  return SQLITE_OK;
-+}
- 
--  assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
--  *pResult = 0.0;   /* Default return value, in case of an error */
-+#ifndef SQLITE_OMIT_DEPRECATED
-+/*
-+** Deprecated external interface.  Internal/core SQLite code
-+** should call sqlite3MemoryAlarm.
-+*/
-+SQLITE_API int sqlite3_memory_alarm(
-+  void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
-+  void *pArg,
-+  sqlite3_int64 iThreshold
-+){
-+  return sqlite3MemoryAlarm(xCallback, pArg, iThreshold);
-+}
-+#endif
- 
--  if( enc==SQLITE_UTF8 ){
--    incr = 1;
-+/*
-+** 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){
-+  sqlite3_int64 priorLimit;
-+  sqlite3_int64 excess;
-+#ifndef SQLITE_OMIT_AUTOINIT
-+  int rc = sqlite3_initialize();
-+  if( rc ) return -1;
-+#endif
-+  sqlite3_mutex_enter(mem0.mutex);
-+  priorLimit = mem0.alarmThreshold;
-+  sqlite3_mutex_leave(mem0.mutex);
-+  if( n<0 ) return priorLimit;
-+  if( n>0 ){
-+    sqlite3MemoryAlarm(softHeapLimitEnforcer, 0, n);
-   }else{
--    int i;
--    incr = 2;
--    assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
--    for(i=3-enc; i<length && z[i]==0; i+=2){}
--    nonNum = i<length;
--    zEnd = z+i+enc-3;
--    z += (enc&1);
--  }
--
--  /* skip leading spaces */
--  while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
--  if( z>=zEnd ) return 0;
--
--  /* get sign of significand */
--  if( *z=='-' ){
--    sign = -1;
--    z+=incr;
--  }else if( *z=='+' ){
--    z+=incr;
-+    sqlite3MemoryAlarm(0, 0, 0);
-   }
-+  excess = sqlite3_memory_used() - n;
-+  if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff));
-+  return priorLimit;
-+}
-+SQLITE_API void sqlite3_soft_heap_limit(int n){
-+  if( n<0 ) n = 0;
-+  sqlite3_soft_heap_limit64(n);
-+}
- 
--  /* skip leading zeroes */
--  while( z<zEnd && z[0]=='0' ) z+=incr, nDigits++;
--
--  /* copy max significant digits to significand */
--  while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
--    s = s*10 + (*z - '0');
--    z+=incr, nDigits++;
-+/*
-+** Initialize the memory allocation subsystem.
-+*/
-+SQLITE_PRIVATE int sqlite3MallocInit(void){
-+  if( sqlite3GlobalConfig.m.xMalloc==0 ){
-+    sqlite3MemSetDefault();
-   }
--
--  /* skip non-significant significand digits
--  ** (increase exponent by d to shift decimal left) */
--  while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++, d++;
--  if( z>=zEnd ) goto do_atof_calc;
--
--  /* if decimal point is present */
--  if( *z=='.' ){
--    z+=incr;
--    /* copy digits from after decimal to significand
--    ** (decrease exponent by d to shift decimal right) */
--    while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
--      s = s*10 + (*z - '0');
--      z+=incr, nDigits++, d--;
--    }
--    /* skip non-significant digits */
--    while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++;
-+  memset(&mem0, 0, sizeof(mem0));
-+  if( sqlite3GlobalConfig.bCoreMutex ){
-+    mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
-   }
--  if( z>=zEnd ) goto do_atof_calc;
--
--  /* if exponent is present */
--  if( *z=='e' || *z=='E' ){
--    z+=incr;
--    eValid = 0;
--    if( z>=zEnd ) goto do_atof_calc;
--    /* get sign of exponent */
--    if( *z=='-' ){
--      esign = -1;
--      z+=incr;
--    }else if( *z=='+' ){
--      z+=incr;
--    }
--    /* copy digits to exponent */
--    while( z<zEnd && sqlite3Isdigit(*z) ){
--      e = e<10000 ? (e*10 + (*z - '0')) : 10000;
--      z+=incr;
--      eValid = 1;
-+  if( sqlite3GlobalConfig.pScratch && sqlite3GlobalConfig.szScratch>=100
-+      && sqlite3GlobalConfig.nScratch>0 ){
-+    int i, n, sz;
-+    ScratchFreeslot *pSlot;
-+    sz = ROUNDDOWN8(sqlite3GlobalConfig.szScratch);
-+    sqlite3GlobalConfig.szScratch = sz;
-+    pSlot = (ScratchFreeslot*)sqlite3GlobalConfig.pScratch;
-+    n = sqlite3GlobalConfig.nScratch;
-+    mem0.pScratchFree = pSlot;
-+    mem0.nScratchFree = n;
-+    for(i=0; i<n-1; i++){
-+      pSlot->pNext = (ScratchFreeslot*)(sz+(char*)pSlot);
-+      pSlot = pSlot->pNext;
-     }
-+    pSlot->pNext = 0;
-+    mem0.pScratchEnd = (void*)&pSlot[1];
-+  }else{
-+    mem0.pScratchEnd = 0;
-+    sqlite3GlobalConfig.pScratch = 0;
-+    sqlite3GlobalConfig.szScratch = 0;
-+    sqlite3GlobalConfig.nScratch = 0;
-   }
--
--  /* skip trailing spaces */
--  if( nDigits && eValid ){
--    while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
--  }
--
--do_atof_calc:
--  /* adjust exponent by d, and update sign */
--  e = (e*esign) + d;
--  if( e<0 ) {
--    esign = -1;
--    e *= -1;
--  } else {
--    esign = 1;
-+  if( sqlite3GlobalConfig.pPage==0 || sqlite3GlobalConfig.szPage<512
-+      || sqlite3GlobalConfig.nPage<1 ){
-+    sqlite3GlobalConfig.pPage = 0;
-+    sqlite3GlobalConfig.szPage = 0;
-+    sqlite3GlobalConfig.nPage = 0;
-   }
-+  return sqlite3GlobalConfig.m.xInit(sqlite3GlobalConfig.m.pAppData);
-+}
- 
--  /* if 0 significand */
--  if( !s ) {
--    /* In the IEEE 754 standard, zero is signed.
--    ** Add the sign if we've seen at least one digit */
--    result = (sign<0 && nDigits) ? -(double)0 : (double)0;
--  } else {
--    /* attempt to reduce exponent */
--    if( esign>0 ){
--      while( s<(LARGEST_INT64/10) && e>0 ) e--,s*=10;
--    }else{
--      while( !(s%10) && e>0 ) e--,s/=10;
--    }
--
--    /* adjust the sign of significand */
--    s = sign<0 ? -s : s;
-+/*
-+** Return true if the heap is currently under memory pressure - in other
-+** words if the amount of heap used is close to the limit set by
-+** sqlite3_soft_heap_limit().
-+*/
-+SQLITE_PRIVATE int sqlite3HeapNearlyFull(void){
-+  return mem0.nearlyFull;
-+}
- 
--    /* if exponent, scale significand as appropriate
--    ** and store in result. */
--    if( e ){
--      LONGDOUBLE_TYPE scale = 1.0;
--      /* attempt to handle extremely small/large numbers better */
--      if( e>307 && e<342 ){
--        while( e%308 ) { scale *= 1.0e+1; e -= 1; }
--        if( esign<0 ){
--          result = s / scale;
--          result /= 1.0e+308;
--        }else{
--          result = s * scale;
--          result *= 1.0e+308;
--        }
--      }else if( e>=342 ){
--        if( esign<0 ){
--          result = 0.0*s;
--        }else{
--          result = 1e308*1e308*s;  /* Infinity */
--        }
--      }else{
--        /* 1.0e+22 is the largest power of 10 than can be 
--        ** represented exactly. */
--        while( e%22 ) { scale *= 1.0e+1; e -= 1; }
--        while( e>0 ) { scale *= 1.0e+22; e -= 22; }
--        if( esign<0 ){
--          result = s / scale;
--        }else{
--          result = s * scale;
--        }
--      }
--    } else {
--      result = (double)s;
--    }
-+/*
-+** Deinitialize the memory allocation subsystem.
-+*/
-+SQLITE_PRIVATE void sqlite3MallocEnd(void){
-+  if( sqlite3GlobalConfig.m.xShutdown ){
-+    sqlite3GlobalConfig.m.xShutdown(sqlite3GlobalConfig.m.pAppData);
-   }
-+  memset(&mem0, 0, sizeof(mem0));
-+}
- 
--  /* store the result */
--  *pResult = result;
--
--  /* return true if number and no extra non-whitespace chracters after */
--  return z>=zEnd && nDigits>0 && eValid && nonNum==0;
--#else
--  return !sqlite3Atoi64(z, pResult, length, enc);
--#endif /* SQLITE_OMIT_FLOATING_POINT */
-+/*
-+** Return the amount of memory currently checked out.
-+*/
-+SQLITE_API sqlite3_int64 sqlite3_memory_used(void){
-+  int n, mx;
-+  sqlite3_int64 res;
-+  sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, 0);
-+  res = (sqlite3_int64)n;  /* Work around bug in Borland C. Ticket #3216 */
-+  return res;
- }
- 
- /*
--** Compare the 19-character string zNum against the text representation
--** value 2^63:  9223372036854775808.  Return negative, zero, or positive
--** if zNum is less than, equal to, or greater than the string.
--** Note that zNum must contain exactly 19 characters.
--**
--** Unlike memcmp() this routine is guaranteed to return the difference
--** in the values of the last digit if the only difference is in the
--** last digit.  So, for example,
--**
--**      compare2pow63("9223372036854775800", 1)
--**
--** will return -8.
-+** Return the maximum amount of memory that has ever been
-+** checked out since either the beginning of this process
-+** or since the most recent reset.
- */
--static int compare2pow63(const char *zNum, int incr){
--  int c = 0;
--  int i;
--                    /* 012345678901234567 */
--  const char *pow63 = "922337203685477580";
--  for(i=0; c==0 && i<18; i++){
--    c = (zNum[i*incr]-pow63[i])*10;
--  }
--  if( c==0 ){
--    c = zNum[18*incr] - '8';
--    testcase( c==(-1) );
--    testcase( c==0 );
--    testcase( c==(+1) );
--  }
--  return c;
-+SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
-+  int n, mx;
-+  sqlite3_int64 res;
-+  sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, resetFlag);
-+  res = (sqlite3_int64)mx;  /* Work around bug in Borland C. Ticket #3216 */
-+  return res;
- }
- 
-+/*
-+** Trigger the alarm 
-+*/
-+static void sqlite3MallocAlarm(int nByte){
-+  void (*xCallback)(void*,sqlite3_int64,int);
-+  sqlite3_int64 nowUsed;
-+  void *pArg;
-+  if( mem0.alarmCallback==0 ) return;
-+  xCallback = mem0.alarmCallback;
-+  nowUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
-+  pArg = mem0.alarmArg;
-+  mem0.alarmCallback = 0;
-+  sqlite3_mutex_leave(mem0.mutex);
-+  xCallback(pArg, nowUsed, nByte);
-+  sqlite3_mutex_enter(mem0.mutex);
-+  mem0.alarmCallback = xCallback;
-+  mem0.alarmArg = pArg;
-+}
- 
- /*
--** Convert zNum to a 64-bit signed integer.
--**
--** If the zNum value is representable as a 64-bit twos-complement 
--** integer, then write that value into *pNum and return 0.
--**
--** If zNum is exactly 9223372036854665808, return 2.  This special
--** case is broken out because while 9223372036854665808 cannot be a 
--** signed 64-bit integer, its negative -9223372036854665808 can be.
--**
--** If zNum is too big for a 64-bit integer and is not
--** 9223372036854665808  or if zNum contains any non-numeric text,
--** then return 1.
--**
--** length is the number of bytes in the string (bytes, not characters).
--** The string is not necessarily zero-terminated.  The encoding is
--** given by enc.
-+** Do a memory allocation with statistics and alarms.  Assume the
-+** lock is already held.
- */
--SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
--  int incr;
--  u64 u = 0;
--  int neg = 0; /* assume positive */
--  int i;
--  int c = 0;
--  int nonNum = 0;
--  const char *zStart;
--  const char *zEnd = zNum + length;
--  assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
--  if( enc==SQLITE_UTF8 ){
--    incr = 1;
--  }else{
--    incr = 2;
--    assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
--    for(i=3-enc; i<length && zNum[i]==0; i+=2){}
--    nonNum = i<length;
--    zEnd = zNum+i+enc-3;
--    zNum += (enc&1);
--  }
--  while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr;
--  if( zNum<zEnd ){
--    if( *zNum=='-' ){
--      neg = 1;
--      zNum+=incr;
--    }else if( *zNum=='+' ){
--      zNum+=incr;
-+static int mallocWithAlarm(int n, void **pp){
-+  int nFull;
-+  void *p;
-+  assert( sqlite3_mutex_held(mem0.mutex) );
-+  nFull = sqlite3GlobalConfig.m.xRoundup(n);
-+  sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n);
-+  if( mem0.alarmCallback!=0 ){
-+    int nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
-+    if( nUsed >= mem0.alarmThreshold - nFull ){
-+      mem0.nearlyFull = 1;
-+      sqlite3MallocAlarm(nFull);
-+    }else{
-+      mem0.nearlyFull = 0;
-     }
-   }
--  zStart = zNum;
--  while( zNum<zEnd && zNum[0]=='0' ){ zNum+=incr; } /* Skip leading zeros. */
--  for(i=0; &zNum[i]<zEnd && (c=zNum[i])>='0' && c<='9'; i+=incr){
--    u = u*10 + c - '0';
-+  p = sqlite3GlobalConfig.m.xMalloc(nFull);
-+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
-+  if( p==0 && mem0.alarmCallback ){
-+    sqlite3MallocAlarm(nFull);
-+    p = sqlite3GlobalConfig.m.xMalloc(nFull);
-   }
--  if( u>LARGEST_INT64 ){
--    *pNum = SMALLEST_INT64;
--  }else if( neg ){
--    *pNum = -(i64)u;
--  }else{
--    *pNum = (i64)u;
-+#endif
-+  if( p ){
-+    nFull = sqlite3MallocSize(p);
-+    sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nFull);
-+    sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, 1);
-   }
--  testcase( i==18 );
--  testcase( i==19 );
--  testcase( i==20 );
--  if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum) || i>19*incr || nonNum ){
--    /* zNum is empty or contains non-numeric text or is longer
--    ** than 19 digits (thus guaranteeing that it is too large) */
--    return 1;
--  }else if( i<19*incr ){
--    /* Less than 19 digits, so we know that it fits in 64 bits */
--    assert( u<=LARGEST_INT64 );
--    return 0;
-+  *pp = p;
-+  return nFull;
-+}
-+
-+/*
-+** 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){
-+  void *p;
-+  if( n<=0               /* IMP: R-65312-04917 */ 
-+   || 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
-+    ** 255 bytes of overhead.  SQLite itself will never use anything near
-+    ** this amount.  The only way to reach the limit is with sqlite3_malloc() */
-+    p = 0;
-+  }else if( sqlite3GlobalConfig.bMemstat ){
-+    sqlite3_mutex_enter(mem0.mutex);
-+    mallocWithAlarm(n, &p);
-+    sqlite3_mutex_leave(mem0.mutex);
-   }else{
--    /* zNum is a 19-digit numbers.  Compare it against 9223372036854775808. */
--    c = compare2pow63(zNum, incr);
--    if( c<0 ){
--      /* zNum is less than 9223372036854775808 so it fits */
--      assert( u<=LARGEST_INT64 );
--      return 0;
--    }else if( c>0 ){
--      /* zNum is greater than 9223372036854775808 so it overflows */
--      return 1;
--    }else{
--      /* zNum is exactly 9223372036854775808.  Fits if negative.  The
--      ** special case 2 overflow if positive */
--      assert( u-1==LARGEST_INT64 );
--      assert( (*pNum)==SMALLEST_INT64 );
--      return neg ? 0 : 2;
--    }
-+    p = sqlite3GlobalConfig.m.xMalloc(n);
-   }
-+  assert( EIGHT_BYTE_ALIGNMENT(p) );  /* IMP: R-04675-44850 */
-+  return p;
- }
- 
- /*
--** If zNum represents an integer that will fit in 32-bits, then set
--** *pValue to that integer and return true.  Otherwise return false.
--**
--** Any non-numeric characters that following zNum are ignored.
--** This is different from sqlite3Atoi64() which requires the
--** input number to be zero-terminated.
-+** This version of the memory allocation is for use by the application.
-+** First make sure the memory subsystem is initialized, then do the
-+** allocation.
- */
--SQLITE_PRIVATE int sqlite3GetInt32(const char *zNum, int *pValue){
--  sqlite_int64 v = 0;
--  int i, c;
--  int neg = 0;
--  if( zNum[0]=='-' ){
--    neg = 1;
--    zNum++;
--  }else if( zNum[0]=='+' ){
--    zNum++;
--  }
--  while( zNum[0]=='0' ) zNum++;
--  for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){
--    v = v*10 + c;
--  }
-+SQLITE_API void *sqlite3_malloc(int n){
-+#ifndef SQLITE_OMIT_AUTOINIT
-+  if( sqlite3_initialize() ) return 0;
-+#endif
-+  return sqlite3Malloc(n);
-+}
- 
--  /* The longest decimal representation of a 32 bit integer is 10 digits:
--  **
--  **             1234567890
--  **     2^31 -> 2147483648
--  */
--  testcase( i==10 );
--  if( i>10 ){
--    return 0;
--  }
--  testcase( v-neg==2147483647 );
--  if( v-neg>2147483647 ){
--    return 0;
-+/*
-+** Each thread may only have a single outstanding allocation from
-+** xScratchMalloc().  We verify this constraint in the single-threaded
-+** case by setting scratchAllocOut to 1 when an allocation
-+** is outstanding clearing it when the allocation is freed.
-+*/
-+#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
-+static int scratchAllocOut = 0;
-+#endif
-+
-+
-+/*
-+** Allocate memory that is to be used and released right away.
-+** This routine is similar to alloca() in that it is not intended
-+** for situations where the memory might be held long-term.  This
-+** routine is intended to get memory to old large transient data
-+** structures that would not normally fit on the stack of an
-+** embedded processor.
-+*/
-+SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){
-+  void *p;
-+  assert( n>0 );
-+
-+  sqlite3_mutex_enter(mem0.mutex);
-+  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);
-+    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 = sqlite3GlobalConfig.m.xMalloc(n);
-+    }
-+    sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH);
-   }
--  if( neg ){
--    v = -v;
-+  assert( sqlite3_mutex_notheld(mem0.mutex) );
-+
-+
-+#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 );
-+  if( p ) scratchAllocOut++;
-+#endif
-+
-+  return p;
-+}
-+SQLITE_PRIVATE void sqlite3ScratchFree(void *p){
-+  if( p ){
-+
-+#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
-+    /* Verify that no more than two scratch allocation per thread
-+    ** is 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 && scratchAllocOut<=2 );
-+    scratchAllocOut--;
-+#endif
-+
-+    if( p>=sqlite3GlobalConfig.pScratch && p<mem0.pScratchEnd ){
-+      /* Release memory from the SQLITE_CONFIG_SCRATCH allocation */
-+      ScratchFreeslot *pSlot;
-+      pSlot = (ScratchFreeslot*)p;
-+      sqlite3_mutex_enter(mem0.mutex);
-+      pSlot->pNext = mem0.pScratchFree;
-+      mem0.pScratchFree = pSlot;
-+      mem0.nScratchFree++;
-+      assert( mem0.nScratchFree <= (u32)sqlite3GlobalConfig.nScratch );
-+      sqlite3StatusAdd(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) );
-+      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);
-+        sqlite3GlobalConfig.m.xFree(p);
-+        sqlite3_mutex_leave(mem0.mutex);
-+      }else{
-+        sqlite3GlobalConfig.m.xFree(p);
-+      }
-+    }
-   }
--  *pValue = (int)v;
--  return 1;
- }
- 
- /*
--** Return a 32-bit integer value extracted from a string.  If the
--** string is not an integer, just return 0.
-+** TRUE if p is a lookaside memory allocation from db
- */
--SQLITE_PRIVATE int sqlite3Atoi(const char *z){
--  int x = 0;
--  if( z ) sqlite3GetInt32(z, &x);
--  return x;
-+#ifndef SQLITE_OMIT_LOOKASIDE
-+static int isLookaside(sqlite3 *db, void *p){
-+  return p && p>=db->lookaside.pStart && p<db->lookaside.pEnd;
- }
-+#else
-+#define isLookaside(A,B) 0
-+#endif
- 
- /*
--** The variable-length integer encoding is as follows:
--**
--** KEY:
--**         A = 0xxxxxxx    7 bits of data and one flag bit
--**         B = 1xxxxxxx    7 bits of data and one flag bit
--**         C = xxxxxxxx    8 bits of data
--**
--**  7 bits - A
--** 14 bits - BA
--** 21 bits - BBA
--** 28 bits - BBBA
--** 35 bits - BBBBA
--** 42 bits - BBBBBA
--** 49 bits - BBBBBBA
--** 56 bits - BBBBBBBA
--** 64 bits - BBBBBBBBC
-+** Return the size of a memory allocation previously obtained from
-+** sqlite3Malloc() or sqlite3_malloc().
- */
-+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 || sqlite3_mutex_held(db->mutex) );
-+  if( db && isLookaside(db, p) ){
-+    return db->lookaside.sz;
-+  }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);
-+  }
-+}
- 
- /*
--** Write a 64-bit variable-length integer to memory starting at p[0].
--** The length of data write will be between 1 and 9 bytes.  The number
--** of bytes written is returned.
--**
--** A variable-length integer consists of the lower 7 bits of each byte
--** for all bytes that have the 8th bit set and one byte with the 8th
--** bit clear.  Except, if we get to the 9th byte, it stores the full
--** 8 bits and is the last byte.
-+** Free memory previously obtained from sqlite3Malloc().
- */
--SQLITE_PRIVATE int sqlite3PutVarint(unsigned char *p, u64 v){
--  int i, j, n;
--  u8 buf[10];
--  if( v & (((u64)0xff000000)<<32) ){
--    p[8] = (u8)v;
--    v >>= 8;
--    for(i=7; i>=0; i--){
--      p[i] = (u8)((v & 0x7f) | 0x80);
--      v >>= 7;
--    }
--    return 9;
--  }    
--  n = 0;
--  do{
--    buf[n++] = (u8)((v & 0x7f) | 0x80);
--    v >>= 7;
--  }while( v!=0 );
--  buf[0] &= 0x7f;
--  assert( n<=9 );
--  for(i=0, j=n-1; j>=0; j--, i++){
--    p[i] = buf[j];
-+SQLITE_API void sqlite3_free(void *p){
-+  if( p==0 ) return;  /* IMP: R-49053-54554 */
-+  assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
-+  assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
-+  if( sqlite3GlobalConfig.bMemstat ){
-+    sqlite3_mutex_enter(mem0.mutex);
-+    sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p));
-+    sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1);
-+    sqlite3GlobalConfig.m.xFree(p);
-+    sqlite3_mutex_leave(mem0.mutex);
-+  }else{
-+    sqlite3GlobalConfig.m.xFree(p);
-   }
--  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.
-+** Free memory that might be associated with a particular database
-+** connection.
- */
--SQLITE_PRIVATE int sqlite3PutVarint32(unsigned char *p, u32 v){
--#ifndef putVarint32
--  if( (v & ~0x7f)==0 ){
--    p[0] = v;
--    return 1;
--  }
-+SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
-+  assert( db==0 || sqlite3_mutex_held(db->mutex) );
-+  if( db ){
-+    if( db->pnBytesFreed ){
-+      *db->pnBytesFreed += sqlite3DbMallocSize(db, p);
-+      return;
-+    }
-+    if( isLookaside(db, p) ){
-+      LookasideSlot *pBuf = (LookasideSlot*)p;
-+#if SQLITE_DEBUG
-+      /* Trash all content in the buffer being freed */
-+      memset(p, 0xaa, db->lookaside.sz);
- #endif
--  if( (v & ~0x3fff)==0 ){
--    p[0] = (u8)((v>>7) | 0x80);
--    p[1] = (u8)(v & 0x7f);
--    return 2;
-+      pBuf->pNext = db->lookaside.pFree;
-+      db->lookaside.pFree = pBuf;
-+      db->lookaside.nOut--;
-+      return;
-+    }
-   }
--  return sqlite3PutVarint(p, v);
-+  assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
-+  assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
-+  assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
-+  sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
-+  sqlite3_free(p);
- }
- 
- /*
--** Bitmasks used by sqlite3GetVarint().  These precomputed constants
--** are defined here rather than simply putting the constant expressions
--** inline in order to work around bugs in the RVT compiler.
--**
--** SLOT_2_0     A mask for  (0x7f<<14) | 0x7f
--**
--** SLOT_4_2_0   A mask for  (0x7f<<28) | SLOT_2_0
-+** Change the size of an existing memory allocation
- */
--#define SLOT_2_0     0x001fc07f
--#define SLOT_4_2_0   0xf01fc07f
--
-+SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, int nBytes){
-+  int nOld, nNew, nDiff;
-+  void *pNew;
-+  if( pOld==0 ){
-+    return sqlite3Malloc(nBytes); /* IMP: R-28354-25769 */
-+  }
-+  if( nBytes<=0 ){
-+    sqlite3_free(pOld); /* IMP: R-31593-10574 */
-+    return 0;
-+  }
-+  if( nBytes>=0x7fffff00 ){
-+    /* The 0x7ffff00 limit term is explained in comments on sqlite3Malloc() */
-+    return 0;
-+  }
-+  nOld = sqlite3MallocSize(pOld);
-+  /* 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);
-+  if( nOld==nNew ){
-+    pNew = pOld;
-+  }else if( sqlite3GlobalConfig.bMemstat ){
-+    sqlite3_mutex_enter(mem0.mutex);
-+    sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, 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);
-+      pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
-+    }
-+    if( pNew ){
-+      nNew = sqlite3MallocSize(pNew);
-+      sqlite3StatusAdd(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 */
-+  return pNew;
-+}
- 
- /*
--** Read a 64-bit variable-length integer from memory starting at p[0].
--** Return the number of bytes read.  The value is stored in *v.
-+** The public interface to sqlite3Realloc.  Make sure that the memory
-+** subsystem is initialized prior to invoking sqliteRealloc.
- */
--SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){
--  u32 a,b,s;
-+SQLITE_API void *sqlite3_realloc(void *pOld, int n){
-+#ifndef SQLITE_OMIT_AUTOINIT
-+  if( sqlite3_initialize() ) return 0;
-+#endif
-+  return sqlite3Realloc(pOld, n);
-+}
- 
--  a = *p;
--  /* a: p0 (unmasked) */
--  if (!(a&0x80))
--  {
--    *v = a;
--    return 1;
--  }
- 
--  p++;
--  b = *p;
--  /* b: p1 (unmasked) */
--  if (!(b&0x80))
--  {
--    a &= 0x7f;
--    a = a<<7;
--    a |= b;
--    *v = a;
--    return 2;
-+/*
-+** Allocate and zero memory.
-+*/ 
-+SQLITE_PRIVATE void *sqlite3MallocZero(int n){
-+  void *p = sqlite3Malloc(n);
-+  if( p ){
-+    memset(p, 0, n);
-   }
-+  return p;
-+}
- 
--  /* Verify that constants are precomputed correctly */
--  assert( SLOT_2_0 == ((0x7f<<14) | (0x7f)) );
--  assert( SLOT_4_2_0 == ((0xfU<<28) | (0x7f<<14) | (0x7f)) );
--
--  p++;
--  a = a<<14;
--  a |= *p;
--  /* a: p0<<14 | p2 (unmasked) */
--  if (!(a&0x80))
--  {
--    a &= SLOT_2_0;
--    b &= 0x7f;
--    b = b<<7;
--    a |= b;
--    *v = a;
--    return 3;
-+/*
-+** Allocate and zero memory.  If the allocation fails, make
-+** the mallocFailed flag in the connection pointer.
-+*/
-+SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3 *db, int n){
-+  void *p = sqlite3DbMallocRaw(db, n);
-+  if( p ){
-+    memset(p, 0, n);
-   }
-+  return p;
-+}
- 
--  /* CSE1 from below */
--  a &= SLOT_2_0;
--  p++;
--  b = b<<14;
--  b |= *p;
--  /* b: p1<<14 | p3 (unmasked) */
--  if (!(b&0x80))
--  {
--    b &= SLOT_2_0;
--    /* moved CSE1 up */
--    /* a &= (0x7f<<14)|(0x7f); */
--    a = a<<7;
--    a |= b;
--    *v = a;
--    return 4;
-+/*
-+** Allocate and zero memory.  If the allocation fails, make
-+** the mallocFailed flag in the connection pointer.
-+**
-+** If db!=0 and db->mallocFailed is true (indicating a prior malloc
-+** failure on the same database connection) then always return 0.
-+** Hence for a particular database connection, once malloc starts
-+** failing, it fails consistently until mallocFailed is reset.
-+** This is an important assumption.  There are many places in the
-+** code that do things like this:
-+**
-+**         int *a = (int*)sqlite3DbMallocRaw(db, 100);
-+**         int *b = (int*)sqlite3DbMallocRaw(db, 200);
-+**         if( b ) a[10] = 9;
-+**
-+** 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){
-+  void *p;
-+  assert( db==0 || sqlite3_mutex_held(db->mutex) );
-+  assert( db==0 || db->pnBytesFreed==0 );
-+#ifndef SQLITE_OMIT_LOOKASIDE
-+  if( db ){
-+    LookasideSlot *pBuf;
-+    if( db->mallocFailed ){
-+      return 0;
-+    }
-+    if( db->lookaside.bEnabled ){
-+      if( n>db->lookaside.sz ){
-+        db->lookaside.anStat[1]++;
-+      }else if( (pBuf = db->lookaside.pFree)==0 ){
-+        db->lookaside.anStat[2]++;
-+      }else{
-+        db->lookaside.pFree = pBuf->pNext;
-+        db->lookaside.nOut++;
-+        db->lookaside.anStat[0]++;
-+        if( db->lookaside.nOut>db->lookaside.mxOut ){
-+          db->lookaside.mxOut = db->lookaside.nOut;
-+        }
-+        return (void*)pBuf;
-+      }
-+    }
-   }
--
--  /* a: p0<<14 | p2 (masked) */
--  /* b: p1<<14 | p3 (unmasked) */
--  /* 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
--  /* moved CSE1 up */
--  /* a &= (0x7f<<14)|(0x7f); */
--  b &= SLOT_2_0;
--  s = a;
--  /* s: p0<<14 | p2 (masked) */
--
--  p++;
--  a = a<<14;
--  a |= *p;
--  /* a: p0<<28 | p2<<14 | p4 (unmasked) */
--  if (!(a&0x80))
--  {
--    /* we can skip these cause they were (effectively) done above in calc'ing s */
--    /* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */
--    /* b &= (0x7f<<14)|(0x7f); */
--    b = b<<7;
--    a |= b;
--    s = s>>18;
--    *v = ((u64)s)<<32 | a;
--    return 5;
-+#else
-+  if( db && db->mallocFailed ){
-+    return 0;
-   }
--
--  /* 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
--  s = s<<7;
--  s |= b;
--  /* s: p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
--
--  p++;
--  b = b<<14;
--  b |= *p;
--  /* b: p1<<28 | p3<<14 | p5 (unmasked) */
--  if (!(b&0x80))
--  {
--    /* we can skip this cause it was (effectively) done above in calc'ing s */
--    /* b &= (0x7f<<28)|(0x7f<<14)|(0x7f); */
--    a &= SLOT_2_0;
--    a = a<<7;
--    a |= b;
--    s = s>>18;
--    *v = ((u64)s)<<32 | a;
--    return 6;
-+#endif
-+  p = sqlite3Malloc(n);
-+  if( !p && db ){
-+    db->mallocFailed = 1;
-   }
-+  sqlite3MemdebugSetType(p, MEMTYPE_DB |
-+         ((db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
-+  return p;
-+}
- 
--  p++;
--  a = a<<14;
--  a |= *p;
--  /* a: p2<<28 | p4<<14 | p6 (unmasked) */
--  if (!(a&0x80))
--  {
--    a &= SLOT_4_2_0;
--    b &= SLOT_2_0;
--    b = b<<7;
--    a |= b;
--    s = s>>11;
--    *v = ((u64)s)<<32 | a;
--    return 7;
-+/*
-+** 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){
-+  void *pNew = 0;
-+  assert( db!=0 );
-+  assert( sqlite3_mutex_held(db->mutex) );
-+  if( db->mallocFailed==0 ){
-+    if( p==0 ){
-+      return sqlite3DbMallocRaw(db, n);
-+    }
-+    if( isLookaside(db, p) ){
-+      if( n<=db->lookaside.sz ){
-+        return p;
-+      }
-+      pNew = sqlite3DbMallocRaw(db, n);
-+      if( pNew ){
-+        memcpy(pNew, p, db->lookaside.sz);
-+        sqlite3DbFree(db, p);
-+      }
-+    }else{
-+      assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
-+      assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
-+      sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
-+      pNew = sqlite3_realloc(p, n);
-+      if( !pNew ){
-+        sqlite3MemdebugSetType(p, MEMTYPE_DB|MEMTYPE_HEAP);
-+        db->mallocFailed = 1;
-+      }
-+      sqlite3MemdebugSetType(pNew, MEMTYPE_DB | 
-+            (db->lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
-+    }
-   }
-+  return pNew;
-+}
- 
--  /* CSE2 from below */
--  a &= SLOT_2_0;
--  p++;
--  b = b<<14;
--  b |= *p;
--  /* b: p3<<28 | p5<<14 | p7 (unmasked) */
--  if (!(b&0x80))
--  {
--    b &= SLOT_4_2_0;
--    /* moved CSE2 up */
--    /* a &= (0x7f<<14)|(0x7f); */
--    a = a<<7;
--    a |= b;
--    s = s>>4;
--    *v = ((u64)s)<<32 | a;
--    return 8;
-+/*
-+** 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){
-+  void *pNew;
-+  pNew = sqlite3DbRealloc(db, p, n);
-+  if( !pNew ){
-+    sqlite3DbFree(db, p);
-   }
--
--  p++;
--  a = a<<15;
--  a |= *p;
--  /* a: p4<<29 | p6<<15 | p8 (unmasked) */
--
--  /* moved CSE2 up */
--  /* a &= (0x7f<<29)|(0x7f<<15)|(0xff); */
--  b &= SLOT_2_0;
--  b = b<<8;
--  a |= b;
--
--  s = s<<4;
--  b = p[-4];
--  b &= 0x7f;
--  b = b>>3;
--  s |= b;
--
--  *v = ((u64)s)<<32 | a;
--
--  return 9;
-+  return pNew;
- }
- 
- /*
--** Read a 32-bit variable-length integer from memory starting at p[0].
--** Return the number of bytes read.  The value is stored in *v.
--**
--** If the varint stored in p[0] is larger than can fit in a 32-bit unsigned
--** integer, then set *v to 0xffffffff.
--**
--** A MACRO version, getVarint32, 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.
-+** Make a copy of a string in memory obtained from sqliteMalloc(). These 
-+** functions call sqlite3MallocRaw() directly instead of sqliteMalloc(). This
-+** is because when memory debugging is turned on, these two functions are 
-+** called via macros that record the current file and line number in the
-+** ThreadData structure.
- */
--SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){
--  u32 a,b;
--
--  /* The 1-byte case.  Overwhelmingly the most common.  Handled inline
--  ** by the getVarin32() macro */
--  a = *p;
--  /* a: p0 (unmasked) */
--#ifndef getVarint32
--  if (!(a&0x80))
--  {
--    /* Values between 0 and 127 */
--    *v = a;
--    return 1;
-+SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3 *db, const char *z){
-+  char *zNew;
-+  size_t n;
-+  if( z==0 ){
-+    return 0;
-   }
--#endif
--
--  /* The 2-byte case */
--  p++;
--  b = *p;
--  /* b: p1 (unmasked) */
--  if (!(b&0x80))
--  {
--    /* Values between 128 and 16383 */
--    a &= 0x7f;
--    a = a<<7;
--    *v = a | b;
--    return 2;
-+  n = sqlite3Strlen30(z) + 1;
-+  assert( (n&0x7fffffff)==n );
-+  zNew = sqlite3DbMallocRaw(db, (int)n);
-+  if( zNew ){
-+    memcpy(zNew, z, n);
-   }
--
--  /* The 3-byte case */
--  p++;
--  a = a<<14;
--  a |= *p;
--  /* a: p0<<14 | p2 (unmasked) */
--  if (!(a&0x80))
--  {
--    /* Values between 16384 and 2097151 */
--    a &= (0x7f<<14)|(0x7f);
--    b &= 0x7f;
--    b = b<<7;
--    *v = a | b;
--    return 3;
-+  return zNew;
-+}
-+SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3 *db, const char *z, int n){
-+  char *zNew;
-+  if( z==0 ){
-+    return 0;
-   }
--
--  /* A 32-bit varint is used to store size information in btrees.
--  ** Objects are rarely larger than 2MiB limit of a 3-byte varint.
--  ** A 3-byte varint is sufficient, for example, to record the size
--  ** of a 1048569-byte BLOB or string.
--  **
--  ** We only unroll the first 1-, 2-, and 3- byte cases.  The very
--  ** rare larger cases can be handled by the slower 64-bit varint
--  ** routine.
--  */
--#if 1
--  {
--    u64 v64;
--    u8 n;
--
--    p -= 2;
--    n = sqlite3GetVarint(p, &v64);
--    assert( n>3 && n<=9 );
--    if( (v64 & SQLITE_MAX_U32)!=v64 ){
--      *v = 0xffffffff;
--    }else{
--      *v = (u32)v64;
--    }
--    return n;
-+  assert( (n&0x7fffffff)==n );
-+  zNew = sqlite3DbMallocRaw(db, n+1);
-+  if( zNew ){
-+    memcpy(zNew, z, n);
-+    zNew[n] = 0;
-   }
-+  return zNew;
-+}
- 
--#else
--  /* For following code (kept for historical record only) shows an
--  ** unrolling for the 3- and 4-byte varint cases.  This code is
--  ** slightly faster, but it is also larger and much harder to test.
--  */
--  p++;
--  b = b<<14;
--  b |= *p;
--  /* b: p1<<14 | p3 (unmasked) */
--  if (!(b&0x80))
--  {
--    /* Values between 2097152 and 268435455 */
--    b &= (0x7f<<14)|(0x7f);
--    a &= (0x7f<<14)|(0x7f);
--    a = a<<7;
--    *v = a | b;
--    return 4;
--  }
-+/*
-+** Create a string from the zFromat argument and the va_list that follows.
-+** Store the string in memory obtained from sqliteMalloc() and make *pz
-+** point to that string.
-+*/
-+SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zFormat, ...){
-+  va_list ap;
-+  char *z;
- 
--  p++;
--  a = a<<14;
--  a |= *p;
--  /* a: p0<<28 | p2<<14 | p4 (unmasked) */
--  if (!(a&0x80))
--  {
--    /* Values  between 268435456 and 34359738367 */
--    a &= SLOT_4_2_0;
--    b &= SLOT_4_2_0;
--    b = b<<7;
--    *v = a | b;
--    return 5;
--  }
-+  va_start(ap, zFormat);
-+  z = sqlite3VMPrintf(db, zFormat, ap);
-+  va_end(ap);
-+  sqlite3DbFree(db, *pz);
-+  *pz = z;
-+}
- 
--  /* We can only reach this point when reading a corrupt database
--  ** file.  In that case we are not in any hurry.  Use the (relatively
--  ** slow) general-purpose sqlite3GetVarint() routine to extract the
--  ** value. */
--  {
--    u64 v64;
--    u8 n;
- 
--    p -= 4;
--    n = sqlite3GetVarint(p, &v64);
--    assert( n>5 && n<=9 );
--    *v = (u32)v64;
--    return n;
-+/*
-+** This function must be called before exiting any API function (i.e. 
-+** returning control to the user) that has called sqlite3_malloc or
-+** sqlite3_realloc.
 +**
-+** The returned value is normally a copy of the second argument to this
-+** function. However, if a malloc() failure has occurred since the previous
-+** invocation SQLITE_NOMEM is returned instead. 
-+**
-+** If the first argument, db, is not NULL and a malloc() error has occurred,
-+** then the connection error-code (the value returned by sqlite3_errcode())
-+** is set to SQLITE_NOMEM.
++** This file implements routines used to report what compile-time options
++** SQLite was built with.
 +*/
-+SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){
-+  /* If the db handle is not NULL, then we must hold the connection handle
-+  ** mutex here. Otherwise the read (and possible write) of db->mallocFailed 
-+  ** 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;
-   }
--#endif
-+  return rc & (db ? db->errMask : 0xff);
- }
- 
-+/************** End of malloc.c **********************************************/
-+/************** Begin file printf.c ******************************************/
- /*
--** Return the number of bytes that will be needed to store the given
--** 64-bit integer.
-+** The "printf" code that follows dates from the 1980's.  It is in
-+** the public domain.  The original comments are included here for
-+** completeness.  They are very out-of-date but might be useful as
-+** an historical reference.  Most of the "enhancements" have been backed
-+** out so that the functionality is now the same as standard printf().
-+**
-+**************************************************************************
-+**
-+** This file contains code for a set of "printf"-like routines.  These
-+** routines format strings much like the printf() from the standard C
-+** library, though the implementation here has enhancements to support
-+** SQLlite.
- */
--SQLITE_PRIVATE int sqlite3VarintLen(u64 v){
--  int i = 0;
--  do{
--    i++;
--    v >>= 7;
--  }while( v!=0 && ALWAYS(i<9) );
--  return i;
--}
--
- 
- /*
--** Read or write a four-byte big-endian integer value.
-+** Conversion types fall into various categories as defined by the
-+** following enumeration.
- */
--SQLITE_PRIVATE u32 sqlite3Get4byte(const u8 *p){
--  return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
--}
--SQLITE_PRIVATE void sqlite3Put4byte(unsigned char *p, u32 v){
--  p[0] = (u8)(v>>24);
--  p[1] = (u8)(v>>16);
--  p[2] = (u8)(v>>8);
--  p[3] = (u8)v;
--}
-+#define etRADIX       1 /* Integer types.  %d, %x, %o, and so forth */
-+#define etFLOAT       2 /* Floating point.  %f */
-+#define etEXP         3 /* Exponentional notation. %e and %E */
-+#define etGENERIC     4 /* Floating or exponential, depending on exponent. %g */
-+#define etSIZE        5 /* Return number of characters processed so far. %n */
-+#define etSTRING      6 /* Strings. %s */
-+#define etDYNSTRING   7 /* Dynamically allocated strings. %z */
-+#define etPERCENT     8 /* Percent symbol. %% */
-+#define etCHARX       9 /* Characters. %c */
-+/* The rest are extensions, not normally found in printf() */
-+#define etSQLESCAPE  10 /* Strings with '\'' doubled.  %q */
-+#define etSQLESCAPE2 11 /* Strings with '\'' doubled and enclosed in '',
-+                          NULL pointers replaced by SQL NULL.  %Q */
-+#define etTOKEN      12 /* a pointer to a Token structure */
-+#define etSRCLIST    13 /* a pointer to a SrcList */
-+#define etPOINTER    14 /* The %p conversion */
-+#define etSQLESCAPE3 15 /* %w -> Strings with '\"' doubled */
-+#define etORDINAL    16 /* %r -> 1st, 2nd, 3rd, 4th, etc.  English only */
- 
-+#define etINVALID     0 /* Any unrecognized conversion type */
- 
- 
- /*
--** Translate a single byte of Hex into an integer.
--** This routine only works if h really is a valid hexadecimal
--** character:  0..9a..fA..F
-+** An "etByte" is an 8-bit unsigned value.
- */
--SQLITE_PRIVATE u8 sqlite3HexToInt(int h){
--  assert( (h>='0' && h<='9') ||  (h>='a' && h<='f') ||  (h>='A' && h<='F') );
--#ifdef SQLITE_ASCII
--  h += 9*(1&(h>>6));
--#endif
--#ifdef SQLITE_EBCDIC
--  h += 9*(1&~(h>>4));
--#endif
--  return (u8)(h & 0xf);
--}
-+typedef unsigned char etByte;
- 
--#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC)
- /*
--** Convert a BLOB literal of the form "x'hhhhhh'" into its binary
--** value.  Return a pointer to its binary value.  Space to hold the
--** binary value has been obtained from malloc and must be freed by
--** the calling routine.
-+** Each builtin conversion character (ex: the 'd' in "%d") is described
-+** by an instance of the following structure
- */
--SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){
--  char *zBlob;
--  int i;
--
--  zBlob = (char *)sqlite3DbMallocRaw(db, n/2 + 1);
--  n--;
--  if( zBlob ){
--    for(i=0; i<n; i+=2){
--      zBlob[i/2] = (sqlite3HexToInt(z[i])<<4) | sqlite3HexToInt(z[i+1]);
--    }
--    zBlob[i/2] = 0;
--  }
--  return zBlob;
--}
--#endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC */
-+typedef struct et_info {   /* Information about each format field */
-+  char fmttype;            /* The format field code letter */
-+  etByte base;             /* The base for radix conversion */
-+  etByte flags;            /* One or more of FLAG_ constants below */
-+  etByte type;             /* Conversion paradigm */
-+  etByte charset;          /* Offset into aDigits[] of the digits string */
-+  etByte prefix;           /* Offset into aPrefix[] of the prefix string */
-+} et_info;
- 
- /*
--** Log an error that is an API call on a connection pointer that should
--** not have been used.  The "type" of connection pointer is given as the
--** argument.  The zType is a word like "NULL" or "closed" or "invalid".
-+** Allowed values for et_info.flags
- */
--static void logBadConnection(const char *zType){
--  sqlite3_log(SQLITE_MISUSE, 
--     "API call with %s database connection pointer",
--     zType
--  );
--}
-+#define FLAG_SIGNED  1     /* True if the value to convert is signed */
-+#define FLAG_INTERN  2     /* True if for internal use only */
-+#define FLAG_STRING  4     /* Allow infinity precision */
 +
++#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
  
- /*
--** Check to make sure we have a valid db pointer.  This test is not
--** foolproof but it does provide some measure of protection against
--** misuse of the interface such as passing in db pointers that are
--** NULL or which have been previously closed.  If this routine returns
--** 1 it means that the db pointer is valid and 0 if it should not be
--** dereferenced for any reason.  The calling function should invoke
--** SQLITE_MISUSE immediately.
--**
--** sqlite3SafetyCheckOk() requires that the db pointer be valid for
--** use.  sqlite3SafetyCheckSickOrOk() allows a db pointer that failed to
--** open properly and is not fit for general use but which can be
--** used as an argument to sqlite3_errmsg() or sqlite3_close().
-+** The following table is searched linearly, so it is good to put the
-+** most frequently used conversion types first.
- */
--SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3 *db){
--  u32 magic;
--  if( db==0 ){
--    logBadConnection("NULL");
--    return 0;
--  }
--  magic = db->magic;
--  if( magic!=SQLITE_MAGIC_OPEN ){
--    if( sqlite3SafetyCheckSickOrOk(db) ){
--      testcase( sqlite3GlobalConfig.xLog!=0 );
--      logBadConnection("unopened");
--    }
--    return 0;
--  }else{
--    return 1;
--  }
--}
--SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3 *db){
--  u32 magic;
--  magic = db->magic;
--  if( magic!=SQLITE_MAGIC_SICK &&
--      magic!=SQLITE_MAGIC_OPEN &&
--      magic!=SQLITE_MAGIC_BUSY ){
--    testcase( sqlite3GlobalConfig.xLog!=0 );
--    logBadConnection("invalid");
--    return 0;
--  }else{
--    return 1;
--  }
--}
--
--/*
--** Attempt to add, substract, or multiply the 64-bit signed value iB against
--** the other 64-bit signed integer at *pA and store the result in *pA.
--** Return 0 on success.  Or if the operation would have resulted in an
--** overflow, leave *pA unchanged and return 1.
--*/
--SQLITE_PRIVATE int sqlite3AddInt64(i64 *pA, i64 iB){
--  i64 iA = *pA;
--  testcase( iA==0 ); testcase( iA==1 );
--  testcase( iB==-1 ); testcase( iB==0 );
--  if( iB>=0 ){
--    testcase( iA>0 && LARGEST_INT64 - iA == iB );
--    testcase( iA>0 && LARGEST_INT64 - iA == iB - 1 );
--    if( iA>0 && LARGEST_INT64 - iA < iB ) return 1;
--    *pA += iB;
--  }else{
--    testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 1 );
--    testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 2 );
--    if( iA<0 && -(iA + LARGEST_INT64) > iB + 1 ) return 1;
--    *pA += iB;
--  }
--  return 0; 
--}
--SQLITE_PRIVATE int sqlite3SubInt64(i64 *pA, i64 iB){
--  testcase( iB==SMALLEST_INT64+1 );
--  if( iB==SMALLEST_INT64 ){
--    testcase( (*pA)==(-1) ); testcase( (*pA)==0 );
--    if( (*pA)>=0 ) return 1;
--    *pA -= iB;
--    return 0;
--  }else{
--    return sqlite3AddInt64(pA, -iB);
--  }
--}
--#define TWOPOWER32 (((i64)1)<<32)
--#define TWOPOWER31 (((i64)1)<<31)
--SQLITE_PRIVATE int sqlite3MulInt64(i64 *pA, i64 iB){
--  i64 iA = *pA;
--  i64 iA1, iA0, iB1, iB0, r;
-+static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
-+static const char aPrefix[] = "-x0\000X0";
-+static const et_info fmtinfo[] = {
-+  {  'd', 10, 1, etRADIX,      0,  0 },
-+  {  's',  0, 4, etSTRING,     0,  0 },
-+  {  'g',  0, 1, etGENERIC,    30, 0 },
-+  {  'z',  0, 4, etDYNSTRING,  0,  0 },
-+  {  'q',  0, 4, etSQLESCAPE,  0,  0 },
-+  {  'Q',  0, 4, etSQLESCAPE2, 0,  0 },
-+  {  'w',  0, 4, etSQLESCAPE3, 0,  0 },
-+  {  'c',  0, 0, etCHARX,      0,  0 },
-+  {  'o',  8, 0, etRADIX,      0,  2 },
-+  {  'u', 10, 0, etRADIX,      0,  0 },
-+  {  'x', 16, 0, etRADIX,      16, 1 },
-+  {  'X', 16, 0, etRADIX,      0,  4 },
-+#ifndef SQLITE_OMIT_FLOATING_POINT
-+  {  'f',  0, 1, etFLOAT,      0,  0 },
-+  {  'e',  0, 1, etEXP,        30, 0 },
-+  {  'E',  0, 1, etEXP,        14, 0 },
-+  {  'G',  0, 1, etGENERIC,    14, 0 },
-+#endif
-+  {  'i', 10, 1, etRADIX,      0,  0 },
-+  {  'n',  0, 0, etSIZE,       0,  0 },
-+  {  '%',  0, 0, etPERCENT,    0,  0 },
-+  {  'p', 16, 0, etPOINTER,    0,  1 },
- 
--  iA1 = iA/TWOPOWER32;
--  iA0 = iA % TWOPOWER32;
--  iB1 = iB/TWOPOWER32;
--  iB0 = iB % TWOPOWER32;
--  if( iA1*iB1 != 0 ) return 1;
--  assert( iA1*iB0==0 || iA0*iB1==0 );
--  r = iA1*iB0 + iA0*iB1;
--  testcase( r==(-TWOPOWER31)-1 );
--  testcase( r==(-TWOPOWER31) );
--  testcase( r==TWOPOWER31 );
--  testcase( r==TWOPOWER31-1 );
--  if( r<(-TWOPOWER31) || r>=TWOPOWER31 ) return 1;
--  r *= TWOPOWER32;
--  if( sqlite3AddInt64(&r, iA0*iB0) ) return 1;
--  *pA = r;
--  return 0;
--}
-+/* All the rest have the FLAG_INTERN bit set and are thus for internal
-+** use only */
-+  {  'T',  0, 2, etTOKEN,      0,  0 },
-+  {  'S',  0, 2, etSRCLIST,    0,  0 },
-+  {  'r', 10, 3, etORDINAL,    0,  0 },
-+};
- 
- /*
--** Compute the absolute value of a 32-bit signed integer, of possible.  Or 
--** if the integer has a value of -2147483648, return +2147483647
-+** If SQLITE_OMIT_FLOATING_POINT is defined, then none of the floating point
-+** conversions will work.
- */
--SQLITE_PRIVATE int sqlite3AbsInt32(int x){
--  if( x>=0 ) return x;
--  if( x==(int)0x80000000 ) return 0x7fffffff;
--  return -x;
--}
--
--#ifdef SQLITE_ENABLE_8_3_NAMES
-+#ifndef SQLITE_OMIT_FLOATING_POINT
- /*
--** If SQLITE_ENABLE_8_3_NAMES is set at compile-time and if the database
--** filename in zBaseFilename is a URI with the "8_3_names=1" parameter and
--** if filename in z[] has a suffix (a.k.a. "extension") that is longer than
--** three characters, then shorten the suffix on z[] to be the last three
--** characters of the original suffix.
--**
--** If SQLITE_ENABLE_8_3_NAMES is set to 2 at compile-time, then always
--** do the suffix shortening regardless of URI parameter.
-+** "*val" is a double such that 0.1 <= *val < 10.0
-+** Return the ascii code for the leading digit of *val, then
-+** multiply "*val" by 10.0 to renormalize.
- **
--** Examples:
-+** Example:
-+**     input:     *val = 3.14159
-+**     output:    *val = 1.4159    function return = '3'
- **
--**     test.db-journal    =>   test.nal
--**     test.db-wal        =>   test.wal
--**     test.db-shm        =>   test.shm
--**     test.db-mj7f3319fa =>   test.9fa
-+** The counter *cnt is incremented each time.  After counter exceeds
-+** 16 (the number of significant digits in a 64-bit float) '0' is
-+** always returned.
- */
--SQLITE_PRIVATE void sqlite3FileSuffix3(const char *zBaseFilename, char *z){
--#if SQLITE_ENABLE_8_3_NAMES<2
--  if( sqlite3_uri_boolean(zBaseFilename, "8_3_names", 0) )
--#endif
--  {
--    int i, sz;
--    sz = sqlite3Strlen30(z);
--    for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){}
--    if( z[i]=='.' && ALWAYS(sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4);
--  }
-+static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
-+  int digit;
-+  LONGDOUBLE_TYPE d;
-+  if( (*cnt)<=0 ) return '0';
-+  (*cnt)--;
-+  digit = (int)*val;
-+  d = digit;
-+  digit += '0';
-+  *val = (*val - d)*10.0;
-+  return (char)digit;
- }
--#endif
-+#endif /* SQLITE_OMIT_FLOATING_POINT */
- 
--/************** End of util.c ************************************************/
--/************** Begin file hash.c ********************************************/
- /*
--** 2001 September 22
--**
--** 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 generic hash-tables
--** used in SQLite.
--*/
--/* #include <assert.h> */
--
--/* Turn bulk memory into a hash table object by initializing the
--** fields of the Hash structure.
--**
--** "pNew" is a pointer to the hash table that is to be initialized.
--*/
--SQLITE_PRIVATE void sqlite3HashInit(Hash *pNew){
--  assert( pNew!=0 );
--  pNew->first = 0;
--  pNew->count = 0;
--  pNew->htsize = 0;
--  pNew->ht = 0;
--}
--
--/* Remove all entries from a hash table.  Reclaim all memory.
--** Call this routine to delete a hash table or to reset a hash table
--** to the empty state.
-+** Append N space characters to the given string buffer.
- */
--SQLITE_PRIVATE void sqlite3HashClear(Hash *pH){
--  HashElem *elem;         /* For looping over all elements of the table */
--
--  assert( pH!=0 );
--  elem = pH->first;
--  pH->first = 0;
--  sqlite3_free(pH->ht);
--  pH->ht = 0;
--  pH->htsize = 0;
--  while( elem ){
--    HashElem *next_elem = elem->next;
--    sqlite3_free(elem);
--    elem = next_elem;
-+SQLITE_PRIVATE void sqlite3AppendSpace(StrAccum *pAccum, int N){
-+  static const char zSpaces[] = "                             ";
-+  while( N>=(int)sizeof(zSpaces)-1 ){
-+    sqlite3StrAccumAppend(pAccum, zSpaces, sizeof(zSpaces)-1);
-+    N -= sizeof(zSpaces)-1;
-+  }
-+  if( N>0 ){
-+    sqlite3StrAccumAppend(pAccum, zSpaces, N);
-   }
--  pH->count = 0;
- }
- 
- /*
--** The hashing function.
-+** On machines with a small stack size, you can redefine the
-+** SQLITE_PRINT_BUF_SIZE to be something smaller, if desired.
- */
--static unsigned int strHash(const char *z, int nKey){
--  int h = 0;
--  assert( nKey>=0 );
--  while( nKey > 0  ){
--    h = (h<<3) ^ h ^ sqlite3UpperToLower[(unsigned char)*z++];
--    nKey--;
--  }
--  return h;
--}
--
-+#ifndef SQLITE_PRINT_BUF_SIZE
-+# define SQLITE_PRINT_BUF_SIZE 70
-+#endif
-+#define etBUFSIZE SQLITE_PRINT_BUF_SIZE  /* Size of the output buffer */
- 
--/* Link pNew element into the hash table pH.  If pEntry!=0 then also
--** insert pNew into the pEntry hash bucket.
-+/*
-+** Render a string given by "fmt" into the StrAccum object.
- */
--static void insertElement(
--  Hash *pH,              /* The complete hash table */
--  struct _ht *pEntry,    /* The entry into which pNew is inserted */
--  HashElem *pNew         /* The element to be inserted */
-+SQLITE_PRIVATE void sqlite3VXPrintf(
-+  StrAccum *pAccum,                  /* Accumulate results here */
-+  int useExtended,                   /* Allow extended %-conversions */
-+  const char *fmt,                   /* Format string */
-+  va_list ap                         /* arguments */
- ){
--  HashElem *pHead;       /* First element already in pEntry */
--  if( pEntry ){
--    pHead = pEntry->count ? pEntry->chain : 0;
--    pEntry->count++;
--    pEntry->chain = pNew;
--  }else{
--    pHead = 0;
--  }
--  if( pHead ){
--    pNew->next = pHead;
--    pNew->prev = pHead->prev;
--    if( pHead->prev ){ pHead->prev->next = pNew; }
--    else             { pH->first = pNew; }
--    pHead->prev = pNew;
--  }else{
--    pNew->next = pH->first;
--    if( pH->first ){ pH->first->prev = pNew; }
--    pNew->prev = 0;
--    pH->first = pNew;
--  }
--}
--
--
--/* Resize the hash table so that it cantains "new_size" buckets.
--**
--** The hash table might fail to resize if sqlite3_malloc() fails or
--** if the new size is the same as the prior size.
--** Return TRUE if the resize occurs and false if not.
--*/
--static int rehash(Hash *pH, unsigned int new_size){
--  struct _ht *new_ht;            /* The new hash table */
--  HashElem *elem, *next_elem;    /* For looping over existing elements */
--
--#if SQLITE_MALLOC_SOFT_LIMIT>0
--  if( new_size*sizeof(struct _ht)>SQLITE_MALLOC_SOFT_LIMIT ){
--    new_size = SQLITE_MALLOC_SOFT_LIMIT/sizeof(struct _ht);
--  }
--  if( new_size==pH->htsize ) return 0;
-+  int c;                     /* Next character in the format string */
-+  char *bufpt;               /* Pointer to the conversion buffer */
-+  int precision;             /* Precision of the current field */
-+  int length;                /* Length of the field */
-+  int idx;                   /* A general purpose loop counter */
-+  int width;                 /* Width of the current field */
-+  etByte flag_leftjustify;   /* True if "-" flag is present */
-+  etByte flag_plussign;      /* True if "+" flag is present */
-+  etByte flag_blanksign;     /* True if " " flag is present */
-+  etByte flag_alternateform; /* True if "#" flag is present */
-+  etByte flag_altform2;      /* True if "!" flag is present */
-+  etByte flag_zeropad;       /* True if field width constant starts with zero */
-+  etByte flag_long;          /* True if "l" flag is present */
-+  etByte flag_longlong;      /* True if the "ll" flag is present */
-+  etByte done;               /* Loop termination flag */
-+  etByte xtype = 0;          /* Conversion paradigm */
-+  char prefix;               /* Prefix character.  "+" or "-" or " " or '\0'. */
-+  sqlite_uint64 longvalue;   /* Value for integer types */
-+  LONGDOUBLE_TYPE realvalue; /* Value for real types */
-+  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 */
-+#ifndef SQLITE_OMIT_FLOATING_POINT
-+  int  exp, e2;              /* exponent of real numbers */
-+  int nsd;                   /* Number of significant digits returned */
-+  double rounder;            /* Used for rounding floating point values */
-+  etByte flag_dp;            /* True if decimal point should be shown */
-+  etByte flag_rtz;           /* True if trailing zeros should be removed */
- #endif
-+  char buf[etBUFSIZE];       /* Conversion buffer */
- 
--  /* The inability to allocates space for a larger hash table is
--  ** a performance hit but it is not a fatal error.  So mark the
--  ** allocation as a benign. Use sqlite3Malloc()/memset(0) instead of 
--  ** sqlite3MallocZero() to make the allocation, as sqlite3MallocZero()
--  ** only zeroes the requested number of bytes whereas this module will
--  ** use the actual amount of space allocated for the hash table (which
--  ** may be larger than the requested amount).
--  */
--  sqlite3BeginBenignMalloc();
--  new_ht = (struct _ht *)sqlite3Malloc( new_size*sizeof(struct _ht) );
--  sqlite3EndBenignMalloc();
-+  bufpt = 0;
-+  for(; (c=(*fmt))!=0; ++fmt){
-+    if( c!='%' ){
-+      int amt;
-+      bufpt = (char *)fmt;
-+      amt = 1;
-+      while( (c=(*++fmt))!='%' && c!=0 ) amt++;
-+      sqlite3StrAccumAppend(pAccum, bufpt, amt);
-+      if( c==0 ) break;
-+    }
-+    if( (c=(*++fmt))==0 ){
-+      sqlite3StrAccumAppend(pAccum, "%", 1);
-+      break;
-+    }
-+    /* Find out what flags are present */
-+    flag_leftjustify = flag_plussign = flag_blanksign = 
-+     flag_alternateform = flag_altform2 = flag_zeropad = 0;
-+    done = 0;
-+    do{
-+      switch( c ){
-+        case '-':   flag_leftjustify = 1;     break;
-+        case '+':   flag_plussign = 1;        break;
-+        case ' ':   flag_blanksign = 1;       break;
-+        case '#':   flag_alternateform = 1;   break;
-+        case '!':   flag_altform2 = 1;        break;
-+        case '0':   flag_zeropad = 1;         break;
-+        default:    done = 1;                 break;
-+      }
-+    }while( !done && (c=(*++fmt))!=0 );
-+    /* Get the field width */
-+    width = 0;
-+    if( c=='*' ){
-+      width = va_arg(ap,int);
-+      if( width<0 ){
-+        flag_leftjustify = 1;
-+        width = -width;
-+      }
-+      c = *++fmt;
-+    }else{
-+      while( c>='0' && c<='9' ){
-+        width = width*10 + c - '0';
-+        c = *++fmt;
-+      }
-+    }
-+    /* Get the precision */
-+    if( c=='.' ){
-+      precision = 0;
-+      c = *++fmt;
-+      if( c=='*' ){
-+        precision = va_arg(ap,int);
-+        if( precision<0 ) precision = -precision;
-+        c = *++fmt;
-+      }else{
-+        while( c>='0' && c<='9' ){
-+          precision = precision*10 + c - '0';
-+          c = *++fmt;
-+        }
-+      }
-+    }else{
-+      precision = -1;
-+    }
-+    /* Get the conversion type modifier */
-+    if( c=='l' ){
-+      flag_long = 1;
-+      c = *++fmt;
-+      if( c=='l' ){
-+        flag_longlong = 1;
-+        c = *++fmt;
-+      }else{
-+        flag_longlong = 0;
-+      }
-+    }else{
-+      flag_long = flag_longlong = 0;
-+    }
-+    /* Fetch the info entry for the field */
-+    infop = &fmtinfo[0];
-+    xtype = etINVALID;
-+    for(idx=0; idx<ArraySize(fmtinfo); idx++){
-+      if( c==fmtinfo[idx].fmttype ){
-+        infop = &fmtinfo[idx];
-+        if( useExtended || (infop->flags & FLAG_INTERN)==0 ){
-+          xtype = infop->type;
-+        }else{
-+          return;
-+        }
-+        break;
-+      }
-+    }
-+    zExtra = 0;
- 
--  if( new_ht==0 ) return 0;
--  sqlite3_free(pH->ht);
--  pH->ht = new_ht;
--  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;
--    next_elem = elem->next;
--    insertElement(pH, &new_ht[h], elem);
--  }
--  return 1;
--}
-+    /*
-+    ** At this point, variables are initialized as follows:
-+    **
-+    **   flag_alternateform          TRUE if a '#' is present.
-+    **   flag_altform2               TRUE if a '!' is present.
-+    **   flag_plussign               TRUE if a '+' is present.
-+    **   flag_leftjustify            TRUE if a '-' is present or if the
-+    **                               field width was negative.
-+    **   flag_zeropad                TRUE if the width began with 0.
-+    **   flag_long                   TRUE if the letter 'l' (ell) prefixed
-+    **                               the conversion character.
-+    **   flag_longlong               TRUE if the letter 'll' (ell ell) prefixed
-+    **                               the conversion character.
-+    **   flag_blanksign              TRUE if a ' ' is present.
-+    **   width                       The specified field width.  This is
-+    **                               always non-negative.  Zero is the default.
-+    **   precision                   The specified precision.  The default
-+    **                               is -1.
-+    **   xtype                       The class of the conversion.
-+    **   infop                       Pointer to the appropriate info struct.
-+    */
-+    switch( xtype ){
-+      case etPOINTER:
-+        flag_longlong = sizeof(char*)==sizeof(i64);
-+        flag_long = sizeof(char*)==sizeof(long int);
-+        /* Fall through into the next case */
-+      case etORDINAL:
-+      case etRADIX:
-+        if( infop->flags & FLAG_SIGNED ){
-+          i64 v;
-+          if( flag_longlong ){
-+            v = va_arg(ap,i64);
-+          }else if( flag_long ){
-+            v = va_arg(ap,long int);
-+          }else{
-+            v = va_arg(ap,int);
-+          }
-+          if( v<0 ){
-+            if( v==SMALLEST_INT64 ){
-+              longvalue = ((u64)1)<<63;
-+            }else{
-+              longvalue = -v;
-+            }
-+            prefix = '-';
-+          }else{
-+            longvalue = v;
-+            if( flag_plussign )        prefix = '+';
-+            else if( flag_blanksign )  prefix = ' ';
-+            else                       prefix = 0;
-+          }
-+        }else{
-+          if( flag_longlong ){
-+            longvalue = va_arg(ap,u64);
-+          }else if( flag_long ){
-+            longvalue = va_arg(ap,unsigned long int);
-+          }else{
-+            longvalue = va_arg(ap,unsigned int);
-+          }
-+          prefix = 0;
-+        }
-+        if( longvalue==0 ) flag_alternateform = 0;
-+        if( flag_zeropad && precision<width-(prefix!=0) ){
-+          precision = width-(prefix!=0);
-+        }
-+        if( precision<etBUFSIZE-10 ){
-+          nOut = etBUFSIZE;
-+          zOut = buf;
-+        }else{
-+          nOut = precision + 10;
-+          zOut = zExtra = sqlite3Malloc( nOut );
-+          if( zOut==0 ){
-+            pAccum->mallocFailed = 1;
-+            return;
-+          }
-+        }
-+        bufpt = &zOut[nOut-1];
-+        if( xtype==etORDINAL ){
-+          static const char zOrd[] = "thstndrd";
-+          int x = (int)(longvalue % 10);
-+          if( x>=4 || (longvalue/10)%10==1 ){
-+            x = 0;
-+          }
-+          *(--bufpt) = zOrd[x*2+1];
-+          *(--bufpt) = zOrd[x*2];
-+        }
-+        {
-+          register const char *cset;      /* Use registers for speed */
-+          register int base;
-+          cset = &aDigits[infop->charset];
-+          base = infop->base;
-+          do{                                           /* Convert to ascii */
-+            *(--bufpt) = cset[longvalue%base];
-+            longvalue = longvalue/base;
-+          }while( longvalue>0 );
-+        }
-+        length = (int)(&zOut[nOut-1]-bufpt);
-+        for(idx=precision-length; idx>0; idx--){
-+          *(--bufpt) = '0';                             /* Zero pad */
-+        }
-+        if( prefix ) *(--bufpt) = prefix;               /* Add sign */
-+        if( flag_alternateform && infop->prefix ){      /* Add "0" or "0x" */
-+          const char *pre;
-+          char x;
-+          pre = &aPrefix[infop->prefix];
-+          for(; (x=(*pre))!=0; pre++) *(--bufpt) = x;
-+        }
-+        length = (int)(&zOut[nOut-1]-bufpt);
-+        break;
-+      case etFLOAT:
-+      case etEXP:
-+      case etGENERIC:
-+        realvalue = va_arg(ap,double);
-+#ifdef SQLITE_OMIT_FLOATING_POINT
-+        length = 0;
-+#else
-+        if( precision<0 ) precision = 6;         /* Set default precision */
-+        if( realvalue<0.0 ){
-+          realvalue = -realvalue;
-+          prefix = '-';
-+        }else{
-+          if( flag_plussign )          prefix = '+';
-+          else if( flag_blanksign )    prefix = ' ';
-+          else                         prefix = 0;
-+        }
-+        if( xtype==etGENERIC && precision>0 ) precision--;
-+#if 0
-+        /* Rounding works like BSD when the constant 0.4999 is used.  Wierd! */
-+        for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1);
-+#else
-+        /* It makes more sense to use 0.5 */
-+        for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1){}
-+#endif
-+        if( xtype==etFLOAT ) realvalue += rounder;
-+        /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
-+        exp = 0;
-+        if( sqlite3IsNaN((double)realvalue) ){
-+          bufpt = "NaN";
-+          length = 3;
-+          break;
-+        }
-+        if( realvalue>0.0 ){
-+          LONGDOUBLE_TYPE scale = 1.0;
-+          while( realvalue>=1e100*scale && exp<=350 ){ scale *= 1e100;exp+=100;}
-+          while( realvalue>=1e64*scale && exp<=350 ){ scale *= 1e64; exp+=64; }
-+          while( realvalue>=1e8*scale && exp<=350 ){ scale *= 1e8; exp+=8; }
-+          while( realvalue>=10.0*scale && exp<=350 ){ scale *= 10.0; exp++; }
-+          realvalue /= scale;
-+          while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; }
-+          while( realvalue<1.0 ){ realvalue *= 10.0; exp--; }
-+          if( exp>350 ){
-+            if( prefix=='-' ){
-+              bufpt = "-Inf";
-+            }else if( prefix=='+' ){
-+              bufpt = "+Inf";
-+            }else{
-+              bufpt = "Inf";
-+            }
-+            length = sqlite3Strlen30(bufpt);
-+            break;
-+          }
-+        }
-+        bufpt = buf;
-+        /*
-+        ** If the field type is etGENERIC, then convert to either etEXP
-+        ** or etFLOAT, as appropriate.
-+        */
-+        if( xtype!=etFLOAT ){
-+          realvalue += rounder;
-+          if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }
-+        }
-+        if( xtype==etGENERIC ){
-+          flag_rtz = !flag_alternateform;
-+          if( exp<-4 || exp>precision ){
-+            xtype = etEXP;
-+          }else{
-+            precision = precision - exp;
-+            xtype = etFLOAT;
-+          }
-+        }else{
-+          flag_rtz = flag_altform2;
-+        }
-+        if( xtype==etEXP ){
-+          e2 = 0;
-+        }else{
-+          e2 = exp;
-+        }
-+        if( e2+precision+width > etBUFSIZE - 15 ){
-+          bufpt = zExtra = sqlite3Malloc( e2+precision+width+15 );
-+          if( bufpt==0 ){
-+            pAccum->mallocFailed = 1;
-+            return;
-+          }
-+        }
-+        zOut = bufpt;
-+        nsd = 16 + flag_altform2*10;
-+        flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
-+        /* The sign in front of the number */
-+        if( prefix ){
-+          *(bufpt++) = prefix;
-+        }
-+        /* Digits prior to the decimal point */
-+        if( e2<0 ){
-+          *(bufpt++) = '0';
-+        }else{
-+          for(; e2>=0; e2--){
-+            *(bufpt++) = et_getdigit(&realvalue,&nsd);
-+          }
-+        }
-+        /* The decimal point */
-+        if( flag_dp ){
-+          *(bufpt++) = '.';
-+        }
-+        /* "0" digits after the decimal point but before the first
-+        ** significant digit of the number */
-+        for(e2++; e2<0; precision--, e2++){
-+          assert( precision>0 );
-+          *(bufpt++) = '0';
-+        }
-+        /* Significant digits after the decimal point */
-+        while( (precision--)>0 ){
-+          *(bufpt++) = et_getdigit(&realvalue,&nsd);
-+        }
-+        /* Remove trailing zeros and the "." if no digits follow the "." */
-+        if( flag_rtz && flag_dp ){
-+          while( bufpt[-1]=='0' ) *(--bufpt) = 0;
-+          assert( bufpt>zOut );
-+          if( bufpt[-1]=='.' ){
-+            if( flag_altform2 ){
-+              *(bufpt++) = '0';
-+            }else{
-+              *(--bufpt) = 0;
-+            }
-+          }
-+        }
-+        /* Add the "eNNN" suffix */
-+        if( xtype==etEXP ){
-+          *(bufpt++) = aDigits[infop->charset];
-+          if( exp<0 ){
-+            *(bufpt++) = '-'; exp = -exp;
-+          }else{
-+            *(bufpt++) = '+';
-+          }
-+          if( exp>=100 ){
-+            *(bufpt++) = (char)((exp/100)+'0');        /* 100's digit */
-+            exp %= 100;
-+          }
-+          *(bufpt++) = (char)(exp/10+'0');             /* 10's digit */
-+          *(bufpt++) = (char)(exp%10+'0');             /* 1's digit */
-+        }
-+        *bufpt = 0;
- 
--/* 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.
--*/
--static HashElem *findElementGivenHash(
--  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. */
--){
--  HashElem *elem;                /* Used to loop thru the element list */
--  int count;                     /* Number of elements left to test */
-+        /* The converted number is in buf[] and zero terminated. Output it.
-+        ** Note that the number is in the usual order, not reversed as with
-+        ** integer conversions. */
-+        length = (int)(bufpt-zOut);
-+        bufpt = zOut;
- 
--  if( pH->ht ){
--    struct _ht *pEntry = &pH->ht[h];
--    elem = pEntry->chain;
--    count = pEntry->count;
--  }else{
--    elem = pH->first;
--    count = pH->count;
--  }
--  while( count-- && ALWAYS(elem) ){
--    if( elem->nKey==nKey && sqlite3StrNICmp(elem->pKey,pKey,nKey)==0 ){ 
--      return elem;
-+        /* Special case:  Add leading zeros if the flag_zeropad flag is
-+        ** set and we are not left justified */
-+        if( flag_zeropad && !flag_leftjustify && length < width){
-+          int i;
-+          int nPad = width - length;
-+          for(i=width; i>=nPad; i--){
-+            bufpt[i] = bufpt[i-nPad];
-+          }
-+          i = prefix!=0;
-+          while( nPad-- ) bufpt[i++] = '0';
-+          length = width;
-+        }
-+#endif /* !defined(SQLITE_OMIT_FLOATING_POINT) */
-+        break;
-+      case etSIZE:
-+        *(va_arg(ap,int*)) = pAccum->nChar;
-+        length = width = 0;
-+        break;
-+      case etPERCENT:
-+        buf[0] = '%';
-+        bufpt = buf;
-+        length = 1;
-+        break;
-+      case etCHARX:
-+        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;
-+        }
-+        bufpt = buf;
-+        break;
-+      case etSTRING:
-+      case etDYNSTRING:
-+        bufpt = va_arg(ap,char*);
-+        if( bufpt==0 ){
-+          bufpt = "";
-+        }else if( xtype==etDYNSTRING ){
-+          zExtra = bufpt;
-+        }
-+        if( precision>=0 ){
-+          for(length=0; length<precision && bufpt[length]; length++){}
-+        }else{
-+          length = sqlite3Strlen30(bufpt);
-+        }
-+        break;
-+      case etSQLESCAPE:
-+      case etSQLESCAPE2:
-+      case etSQLESCAPE3: {
-+        int i, j, k, n, isnull;
-+        int needQuote;
-+        char ch;
-+        char q = ((xtype==etSQLESCAPE3)?'"':'\'');   /* Quote character */
-+        char *escarg = va_arg(ap,char*);
-+        isnull = escarg==0;
-+        if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
-+        k = precision;
-+        for(i=n=0; k!=0 && (ch=escarg[i])!=0; i++, k--){
-+          if( ch==q )  n++;
-+        }
-+        needQuote = !isnull && xtype==etSQLESCAPE2;
-+        n += i + 1 + needQuote*2;
-+        if( n>etBUFSIZE ){
-+          bufpt = zExtra = sqlite3Malloc( n );
-+          if( bufpt==0 ){
-+            pAccum->mallocFailed = 1;
-+            return;
-+          }
-+        }else{
-+          bufpt = buf;
-+        }
-+        j = 0;
-+        if( needQuote ) bufpt[j++] = q;
-+        k = i;
-+        for(i=0; i<k; i++){
-+          bufpt[j++] = ch = escarg[i];
-+          if( ch==q ) bufpt[j++] = ch;
-+        }
-+        if( needQuote ) bufpt[j++] = q;
-+        bufpt[j] = 0;
-+        length = j;
-+        /* The precision in %q and %Q means how many input characters to
-+        ** consume, not the length of the output...
-+        ** if( precision>=0 && precision<length ) length = precision; */
-+        break;
-+      }
-+      case etTOKEN: {
-+        Token *pToken = va_arg(ap, Token*);
-+        if( pToken ){
-+          sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n);
-+        }
-+        length = width = 0;
-+        break;
-+      }
-+      case etSRCLIST: {
-+        SrcList *pSrc = va_arg(ap, SrcList*);
-+        int k = va_arg(ap, int);
-+        struct SrcList_item *pItem = &pSrc->a[k];
-+        assert( k>=0 && k<pSrc->nSrc );
-+        if( pItem->zDatabase ){
-+          sqlite3StrAccumAppend(pAccum, pItem->zDatabase, -1);
-+          sqlite3StrAccumAppend(pAccum, ".", 1);
-+        }
-+        sqlite3StrAccumAppend(pAccum, pItem->zName, -1);
-+        length = width = 0;
-+        break;
-+      }
-+      default: {
-+        assert( xtype==etINVALID );
-+        return;
-+      }
-+    }/* End switch over the format type */
-+    /*
-+    ** The text of the conversion is pointed to by "bufpt" and is
-+    ** "length" characters long.  The field width is "width".  Do
-+    ** the output.
-+    */
-+    if( !flag_leftjustify ){
-+      register int nspace;
-+      nspace = width-length;
-+      if( nspace>0 ){
-+        sqlite3AppendSpace(pAccum, nspace);
-+      }
-     }
--    elem = elem->next;
--  }
--  return 0;
--}
-+    if( length>0 ){
-+      sqlite3StrAccumAppend(pAccum, bufpt, length);
-+    }
-+    if( flag_leftjustify ){
-+      register int nspace;
-+      nspace = width-length;
-+      if( nspace>0 ){
-+        sqlite3AppendSpace(pAccum, nspace);
-+      }
-+    }
-+    sqlite3_free(zExtra);
-+  }/* End for loop over the format string */
-+} /* End of function */
- 
--/* Remove a single entry from the hash table given a pointer to that
--** element and a hash on the element's key.
-+/*
-+** Append N bytes of text from z to the StrAccum object.
- */
--static void removeElementGivenHash(
--  Hash *pH,         /* The pH containing "elem" */
--  HashElem* elem,   /* The element to be removed from the pH */
--  unsigned int h    /* Hash value for the element */
--){
--  struct _ht *pEntry;
--  if( elem->prev ){
--    elem->prev->next = elem->next; 
--  }else{
--    pH->first = elem->next;
-+SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
-+  assert( z!=0 || N==0 );
-+  if( p->tooBig | p->mallocFailed ){
-+    testcase(p->tooBig);
-+    testcase(p->mallocFailed);
-+    return;
-   }
--  if( elem->next ){
--    elem->next->prev = elem->prev;
-+  assert( p->zText!=0 || p->nChar==0 );
-+  if( N<0 ){
-+    N = sqlite3Strlen30(z);
-   }
--  if( pH->ht ){
--    pEntry = &pH->ht[h];
--    if( pEntry->chain==elem ){
--      pEntry->chain = elem->next;
--    }
--    pEntry->count--;
--    assert( pEntry->count>=0 );
-+  if( N==0 || NEVER(z==0) ){
-+    return;
-   }
--  sqlite3_free( elem );
--  pH->count--;
--  if( pH->count==0 ){
--    assert( pH->first==0 );
--    assert( pH->count==0 );
--    sqlite3HashClear(pH);
-+  if( p->nChar+N >= p->nAlloc ){
-+    char *zNew;
-+    if( !p->useMalloc ){
-+      p->tooBig = 1;
-+      N = p->nAlloc - p->nChar - 1;
-+      if( N<=0 ){
-+        return;
-+      }
-+    }else{
-+      char *zOld = (p->zText==p->zBase ? 0 : p->zText);
-+      i64 szNew = p->nChar;
-+      szNew += N + 1;
-+      if( szNew > p->mxAlloc ){
-+        sqlite3StrAccumReset(p);
-+        p->tooBig = 1;
-+        return;
-+      }else{
-+        p->nAlloc = (int)szNew;
-+      }
-+      if( p->useMalloc==1 ){
-+        zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
-+      }else{
-+        zNew = sqlite3_realloc(zOld, p->nAlloc);
-+      }
-+      if( zNew ){
-+        if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
-+        p->zText = zNew;
-+      }else{
-+        p->mallocFailed = 1;
-+        sqlite3StrAccumReset(p);
-+        return;
-+      }
-+    }
-   }
-+  assert( p->zText );
-+  memcpy(&p->zText[p->nChar], z, N);
-+  p->nChar += N;
- }
- 
--/* 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
--** found, or NULL if there is no match.
-+/*
-+** Finish off a string by making sure it is zero-terminated.
-+** Return a pointer to the resulting string.  Return a NULL
-+** pointer if any kind of error was encountered.
- */
--SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey, int nKey){
--  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;
-+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->zText ){
-+        memcpy(p->zText, p->zBase, p->nChar+1);
-+      }else{
-+        p->mallocFailed = 1;
-+      }
-+    }
-   }
--  elem = findElementGivenHash(pH, pKey, nKey, h);
--  return elem ? elem->data : 0;
-+  return p->zText;
- }
- 
--/* Insert an element into the hash table pH.  The key is pKey,nKey
--** and the data is "data".
--**
--** If no element exists with a matching key, then a new
--** element is created and NULL is returned.
--**
--** If another element already exists with the same key, then the
--** new data replaces the old data and the old data is returned.
--** The key is not copied in this instance.  If a malloc fails, then
--** the new data is returned and the hash table is unchanged.
--**
--** If the "data" parameter to this function is NULL, then the
--** element corresponding to "key" is removed from the hash table.
-+/*
-+** Reset an StrAccum string.  Reclaim all malloced memory.
- */
--SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, int nKey, 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 */
+-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
 -
--  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);
--  if( elem ){
--    void *old_data = elem->data;
--    if( data==0 ){
--      removeElementGivenHash(pH,elem,h);
-+SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum *p){
-+  if( p->zText!=p->zBase ){
-+    if( p->useMalloc==1 ){
-+      sqlite3DbFree(p->db, p->zText);
-     }else{
--      elem->data = data;
--      elem->pKey = pKey;
--      assert(nKey==elem->nKey);
--    }
--    return old_data;
--  }
--  if( data==0 ) return 0;
--  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;
-+      sqlite3_free(p->zText);
-     }
-   }
--  if( pH->ht ){
--    insertElement(pH, &pH->ht[h], new_elem);
--  }else{
--    insertElement(pH, 0, new_elem);
--  }
--  return 0;
-+  p->zText = 0;
- }
- 
--/************** End of hash.c ************************************************/
--/************** Begin file opcodes.c *****************************************/
--/* Automatically generated.  Do not edit */
--/* See the mkopcodec.awk script for details. */
--#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
--SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
-- static const char *const azName[] = { "?",
--     /*   1 */ "Goto",
--     /*   2 */ "Gosub",
--     /*   3 */ "Return",
--     /*   4 */ "Yield",
--     /*   5 */ "HaltIfNull",
--     /*   6 */ "Halt",
--     /*   7 */ "Integer",
--     /*   8 */ "Int64",
--     /*   9 */ "String",
--     /*  10 */ "Null",
--     /*  11 */ "Blob",
--     /*  12 */ "Variable",
--     /*  13 */ "Move",
--     /*  14 */ "Copy",
--     /*  15 */ "SCopy",
--     /*  16 */ "ResultRow",
--     /*  17 */ "CollSeq",
--     /*  18 */ "Function",
--     /*  19 */ "Not",
--     /*  20 */ "AddImm",
--     /*  21 */ "MustBeInt",
--     /*  22 */ "RealAffinity",
--     /*  23 */ "Permutation",
--     /*  24 */ "Compare",
--     /*  25 */ "Jump",
--     /*  26 */ "Once",
--     /*  27 */ "If",
--     /*  28 */ "IfNot",
--     /*  29 */ "Column",
--     /*  30 */ "Affinity",
--     /*  31 */ "MakeRecord",
--     /*  32 */ "Count",
--     /*  33 */ "Savepoint",
--     /*  34 */ "AutoCommit",
--     /*  35 */ "Transaction",
--     /*  36 */ "ReadCookie",
--     /*  37 */ "SetCookie",
--     /*  38 */ "VerifyCookie",
--     /*  39 */ "OpenRead",
--     /*  40 */ "OpenWrite",
--     /*  41 */ "OpenAutoindex",
--     /*  42 */ "OpenEphemeral",
--     /*  43 */ "SorterOpen",
--     /*  44 */ "OpenPseudo",
--     /*  45 */ "Close",
--     /*  46 */ "SeekLt",
--     /*  47 */ "SeekLe",
--     /*  48 */ "SeekGe",
--     /*  49 */ "SeekGt",
--     /*  50 */ "Seek",
--     /*  51 */ "NotFound",
--     /*  52 */ "Found",
--     /*  53 */ "IsUnique",
--     /*  54 */ "NotExists",
--     /*  55 */ "Sequence",
--     /*  56 */ "NewRowid",
--     /*  57 */ "Insert",
--     /*  58 */ "InsertInt",
--     /*  59 */ "Delete",
--     /*  60 */ "ResetCount",
--     /*  61 */ "SorterCompare",
--     /*  62 */ "SorterData",
--     /*  63 */ "RowKey",
--     /*  64 */ "RowData",
--     /*  65 */ "Rowid",
--     /*  66 */ "NullRow",
--     /*  67 */ "Last",
--     /*  68 */ "Or",
--     /*  69 */ "And",
--     /*  70 */ "SorterSort",
--     /*  71 */ "Sort",
--     /*  72 */ "Rewind",
--     /*  73 */ "IsNull",
--     /*  74 */ "NotNull",
--     /*  75 */ "Ne",
--     /*  76 */ "Eq",
--     /*  77 */ "Gt",
--     /*  78 */ "Le",
--     /*  79 */ "Lt",
--     /*  80 */ "Ge",
--     /*  81 */ "SorterNext",
--     /*  82 */ "BitAnd",
--     /*  83 */ "BitOr",
--     /*  84 */ "ShiftLeft",
--     /*  85 */ "ShiftRight",
--     /*  86 */ "Add",
--     /*  87 */ "Subtract",
--     /*  88 */ "Multiply",
--     /*  89 */ "Divide",
--     /*  90 */ "Remainder",
--     /*  91 */ "Concat",
--     /*  92 */ "Prev",
--     /*  93 */ "BitNot",
--     /*  94 */ "String8",
--     /*  95 */ "Next",
--     /*  96 */ "SorterInsert",
--     /*  97 */ "IdxInsert",
--     /*  98 */ "IdxDelete",
--     /*  99 */ "IdxRowid",
--     /* 100 */ "IdxLT",
--     /* 101 */ "IdxGE",
--     /* 102 */ "Destroy",
--     /* 103 */ "Clear",
--     /* 104 */ "CreateIndex",
--     /* 105 */ "CreateTable",
--     /* 106 */ "ParseSchema",
--     /* 107 */ "LoadAnalysis",
--     /* 108 */ "DropTable",
--     /* 109 */ "DropIndex",
--     /* 110 */ "DropTrigger",
--     /* 111 */ "IntegrityCk",
--     /* 112 */ "RowSetAdd",
--     /* 113 */ "RowSetRead",
--     /* 114 */ "RowSetTest",
--     /* 115 */ "Program",
--     /* 116 */ "Param",
--     /* 117 */ "FkCounter",
--     /* 118 */ "FkIfZero",
--     /* 119 */ "MemMax",
--     /* 120 */ "IfPos",
--     /* 121 */ "IfNeg",
--     /* 122 */ "IfZero",
--     /* 123 */ "AggStep",
--     /* 124 */ "AggFinal",
--     /* 125 */ "Checkpoint",
--     /* 126 */ "JournalMode",
--     /* 127 */ "Vacuum",
--     /* 128 */ "IncrVacuum",
--     /* 129 */ "Expire",
--     /* 130 */ "Real",
--     /* 131 */ "TableLock",
--     /* 132 */ "VBegin",
--     /* 133 */ "VCreate",
--     /* 134 */ "VDestroy",
--     /* 135 */ "VOpen",
--     /* 136 */ "VFilter",
--     /* 137 */ "VColumn",
--     /* 138 */ "VNext",
--     /* 139 */ "VRename",
--     /* 140 */ "VUpdate",
--     /* 141 */ "ToText",
--     /* 142 */ "ToBlob",
--     /* 143 */ "ToNumeric",
--     /* 144 */ "ToInt",
--     /* 145 */ "ToReal",
--     /* 146 */ "Pagecount",
--     /* 147 */ "MaxPgcnt",
--     /* 148 */ "Trace",
--     /* 149 */ "Noop",
--     /* 150 */ "Explain",
--  };
--  return azName[i];
-+/*
-+** Initialize a string accumulator
-+*/
-+SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n, int mx){
-+  p->zText = p->zBase = zBase;
-+  p->db = 0;
-+  p->nChar = 0;
-+  p->nAlloc = n;
-+  p->mxAlloc = mx;
-+  p->useMalloc = 1;
-+  p->tooBig = 0;
-+  p->mallocFailed = 0;
- }
--#endif
- 
--/************** End of opcodes.c *********************************************/
--/************** Begin file os_unix.c *****************************************/
- /*
--** 2004 May 22
--**
--** 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 VFS implementation for unix-like operating systems
--** include Linux, MacOSX, *BSD, QNX, VxWorks, AIX, HPUX, and others.
--**
--** There are actually several different VFS implementations in this file.
--** The differences are in the way that file locking is done.  The default
--** implementation uses Posix Advisory Locks.  Alternative implementations
--** use flock(), dot-files, various proprietary locking schemas, or simply
--** skip locking all together.
--**
--** This source file is organized into divisions where the logic for various
--** subfunctions is contained within the appropriate division.  PLEASE
--** KEEP THE STRUCTURE OF THIS FILE INTACT.  New code should be placed
--** in the correct division and should be clearly labeled.
--**
--** The layout of divisions is as follows:
--**
--**   *  General-purpose declarations and utility functions.
--**   *  Unique file ID logic used by VxWorks.
--**   *  Various locking primitive implementations (all except proxy locking):
--**      + for Posix Advisory Locks
--**      + for no-op locks
--**      + for dot-file locks
--**      + for flock() locking
--**      + for named semaphore locks (VxWorks only)
--**      + for AFP filesystem locks (MacOSX only)
--**   *  sqlite3_file methods not associated with locking.
--**   *  Definitions of sqlite3_io_methods objects for all locking
--**      methods plus "finder" functions for each locking method.
--**   *  sqlite3_vfs method implementations.
--**   *  Locking primitives for the proxy uber-locking-method. (MacOSX only)
--**   *  Definitions of sqlite3_vfs objects for all locking methods
--**      plus implementations of sqlite3_os_init() and sqlite3_os_end().
-+** Print into memory obtained from sqliteMalloc().  Use the internal
-+** %-conversion extensions.
- */
--#if SQLITE_OS_UNIX              /* This file is used on unix only */
-+SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){
-+  char *z;
-+  char zBase[SQLITE_PRINT_BUF_SIZE];
-+  StrAccum acc;
-+  assert( db!=0 );
-+  sqlite3StrAccumInit(&acc, zBase, sizeof(zBase),
-+                      db->aLimit[SQLITE_LIMIT_LENGTH]);
-+  acc.db = db;
-+  sqlite3VXPrintf(&acc, 1, zFormat, ap);
-+  z = sqlite3StrAccumFinish(&acc);
-+  if( acc.mallocFailed ){
-+    db->mallocFailed = 1;
-+  }
-+  return z;
-+}
- 
--/* Use posix_fallocate() if it is available
-+/*
-+** Print into memory obtained from sqliteMalloc().  Use the internal
-+** %-conversion extensions.
- */
--#if !defined(HAVE_POSIX_FALLOCATE) \
--      && (_XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L)
--# define HAVE_POSIX_FALLOCATE 1
--#endif
-+SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3 *db, const char *zFormat, ...){
-+  va_list ap;
-+  char *z;
-+  va_start(ap, zFormat);
-+  z = sqlite3VMPrintf(db, zFormat, ap);
-+  va_end(ap);
-+  return z;
-+}
- 
- /*
--** There are various methods for file locking used for concurrency
--** control:
-+** Like sqlite3MPrintf(), but call sqlite3DbFree() on zStr after formatting
-+** the string and before returnning.  This routine is intended to be used
-+** to modify an existing string.  For example:
- **
--**   1. POSIX locking (the default),
--**   2. No locking,
--**   3. Dot-file locking,
--**   4. flock() locking,
--**   5. AFP locking (OSX only),
--**   6. Named POSIX semaphores (VXWorks only),
--**   7. proxy locking. (OSX only)
-+**       x = sqlite3MPrintf(db, x, "prefix %s suffix", x);
- **
--** Styles 4, 5, and 7 are only available of SQLITE_ENABLE_LOCKING_STYLE
--** is defined to 1.  The SQLITE_ENABLE_LOCKING_STYLE also enables automatic
--** selection of the appropriate locking style based on the filesystem
--** where the database is located.  
- */
--#if !defined(SQLITE_ENABLE_LOCKING_STYLE)
--#  if defined(__APPLE__)
--#    define SQLITE_ENABLE_LOCKING_STYLE 1
--#  else
--#    define SQLITE_ENABLE_LOCKING_STYLE 0
--#  endif
-+SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3 *db, char *zStr, const char *zFormat, ...){
-+  va_list ap;
-+  char *z;
-+  va_start(ap, zFormat);
-+  z = sqlite3VMPrintf(db, zFormat, ap);
-+  va_end(ap);
-+  sqlite3DbFree(db, zStr);
-+  return z;
-+}
-+
-+/*
-+** Print into memory obtained from sqlite3_malloc().  Omit the internal
-+** %-conversion extensions.
-+*/
-+SQLITE_API char *sqlite3_vmprintf(const char *zFormat, va_list ap){
-+  char *z;
-+  char zBase[SQLITE_PRINT_BUF_SIZE];
-+  StrAccum acc;
-+#ifndef SQLITE_OMIT_AUTOINIT
-+  if( sqlite3_initialize() ) return 0;
- #endif
-+  sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
-+  acc.useMalloc = 2;
-+  sqlite3VXPrintf(&acc, 0, zFormat, ap);
-+  z = sqlite3StrAccumFinish(&acc);
-+  return z;
-+}
- 
- /*
--** Define the OS_VXWORKS pre-processor macro to 1 if building on 
--** vxworks, or 0 otherwise.
-+** Print into memory obtained from sqlite3_malloc()().  Omit the internal
-+** %-conversion extensions.
- */
--#ifndef OS_VXWORKS
--#  if defined(__RTP__) || defined(_WRS_KERNEL)
--#    define OS_VXWORKS 1
--#  else
--#    define OS_VXWORKS 0
--#  endif
-+SQLITE_API char *sqlite3_mprintf(const char *zFormat, ...){
-+  va_list ap;
-+  char *z;
-+#ifndef SQLITE_OMIT_AUTOINIT
-+  if( sqlite3_initialize() ) return 0;
- #endif
-+  va_start(ap, zFormat);
-+  z = sqlite3_vmprintf(zFormat, ap);
-+  va_end(ap);
-+  return z;
-+}
  
  /*
--** These #defines should enable >2GB file support on Posix if the
--** underlying operating system supports it.  If the OS lacks
--** large file support, these should be no-ops.
-+** sqlite3_snprintf() works like snprintf() except that it ignores the
-+** current locale settings.  This is important for SQLite because we
-+** are not able to use a "," as the decimal point in place of "." as
-+** specified by some locales.
- **
--** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
--** on the compiler command line.  This is necessary if you are compiling
--** on a recent machine (ex: RedHat 7.2) but you want your code to work
--** on an older machine (ex: RedHat 6.0).  If you compile on RedHat 7.2
--** without this option, LFS is enable.  But LFS does not exist in the kernel
--** in RedHat 6.0, so the code won't work.  Hence, for maximum binary
--** portability you should omit LFS.
-+** Oops:  The first two arguments of sqlite3_snprintf() are backwards
-+** from the snprintf() standard.  Unfortunately, it is too late to change
-+** this without breaking compatibility, so we just have to live with the
-+** mistake.
- **
--** The previous paragraph was written in 2005.  (This paragraph is written
--** on 2008-11-28.) These days, all Linux kernels support large files, so
--** you should probably leave LFS enabled.  But some embedded platforms might
--** lack LFS in which case the SQLITE_DISABLE_LFS macro might still be useful.
-+** sqlite3_vsnprintf() is the varargs version.
- */
--#ifndef SQLITE_DISABLE_LFS
--# define _LARGE_FILE       1
--# ifndef _FILE_OFFSET_BITS
--#   define _FILE_OFFSET_BITS 64
--# endif
--# define _LARGEFILE_SOURCE 1
--#endif
-+SQLITE_API char *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;
-+  sqlite3VXPrintf(&acc, 0, zFormat, ap);
-+  return sqlite3StrAccumFinish(&acc);
-+}
-+SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
-+  char *z;
-+  va_list ap;
-+  va_start(ap,zFormat);
-+  z = sqlite3_vsnprintf(n, zBuf, zFormat, ap);
-+  va_end(ap);
-+  return z;
-+}
- 
- /*
--** standard include files.
-+** This is the routine that actually formats the sqlite3_log() message.
-+** We house it in a separate routine from sqlite3_log() to avoid using
-+** stack space on small-stack systems when logging is disabled.
-+**
-+** sqlite3_log() must render into a static buffer.  It cannot dynamically
-+** allocate memory because it might be called while the memory allocator
-+** mutex is held.
- */
--#include <sys/types.h>
--#include <sys/stat.h>
--#include <fcntl.h>
--#include <unistd.h>
--/* #include <time.h> */
--#include <sys/time.h>
--#include <errno.h>
--#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
+ ** An array of names of all compile-time options.  This array should 
+@@ -22968,7 +26347,7 @@
+ #include <sys/time.h>
+ #include <errno.h>
+ #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
 -#include <sys/mman.h>
--#endif
--
--
--#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
--#endif /* SQLITE_ENABLE_LOCKING_STYLE */
--
--#if defined(__APPLE__) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS)
--# include <sys/mount.h>
--#endif
-+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 */
- 
--#ifdef HAVE_UTIME
--# include <utime.h>
--#endif
-+  sqlite3StrAccumInit(&acc, zMsg, sizeof(zMsg), 0);
-+  acc.useMalloc = 0;
-+  sqlite3VXPrintf(&acc, 0, zFormat, ap);
-+  sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
-+                           sqlite3StrAccumFinish(&acc));
-+}
- 
- /*
--** Allowed values of unixFile.fsFlags
-+** Format and write a message to the log if logging is enabled.
- */
--#define SQLITE_FSFLAGS_IS_MSDOS     0x1
-+SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...){
-+  va_list ap;                             /* Vararg list */
-+  if( sqlite3GlobalConfig.xLog ){
-+    va_start(ap, zFormat);
-+    renderLogMsg(iErrCode, zFormat, ap);
-+    va_end(ap);
-+  }
-+}
- 
-+#if defined(SQLITE_DEBUG)
- /*
--** If we are to be thread-safe, include the pthreads header and define
--** the SQLITE_UNIX_THREADS macro.
-+** A version of printf() that understands %lld.  Used for debugging.
-+** The printf() built into some versions of windows does not understand %lld
-+** and segfaults if you give it a long long int.
- */
--#if SQLITE_THREADSAFE
--/* # include <pthread.h> */
--# define SQLITE_UNIX_THREADS 1
-+SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){
-+  va_list ap;
-+  StrAccum acc;
-+  char zBuf[500];
-+  sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0);
-+  acc.useMalloc = 0;
-+  va_start(ap,zFormat);
-+  sqlite3VXPrintf(&acc, 0, zFormat, ap);
-+  va_end(ap);
-+  sqlite3StrAccumFinish(&acc);
-+  fprintf(stdout,"%s", zBuf);
-+  fflush(stdout);
-+}
- #endif
- 
-+#ifndef SQLITE_OMIT_TRACE
- /*
--** Default permissions when creating a new file
-+** variable-argument wrapper around sqlite3VXPrintf().
- */
--#ifndef SQLITE_DEFAULT_FILE_PERMISSIONS
--# define SQLITE_DEFAULT_FILE_PERMISSIONS 0644
-+SQLITE_PRIVATE void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){
-+  va_list ap;
-+  va_start(ap,zFormat);
-+  sqlite3VXPrintf(p, 1, zFormat, ap);
-+  va_end(ap);
-+}
- #endif
- 
-+/************** End of printf.c **********************************************/
-+/************** Begin file random.c ******************************************/
- /*
--** Default permissions when creating auto proxy dir
-+** 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 file contains code to implement a pseudo-random number
-+** generator (PRNG) for SQLite.
-+**
-+** Random numbers are used by some of the database backends in order
-+** to generate random integer keys for tables or random filenames.
- */
--#ifndef SQLITE_DEFAULT_PROXYDIR_PERMISSIONS
--# define SQLITE_DEFAULT_PROXYDIR_PERMISSIONS 0755
--#endif
- 
--/*
--** Maximum supported path-length.
--*/
--#define MAX_PATHNAME 512
- 
--/*
--** 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
-+/* All threads share a single random number generator.
-+** This structure is the current state of the generator.
- */
--#define IS_LOCK_ERROR(x)  ((x != SQLITE_OK) && (x != SQLITE_BUSY))
--
--/* Forward references */
--typedef struct unixShm unixShm;               /* Connection shared memory */
--typedef struct unixShmNode unixShmNode;       /* Shared memory instance */
--typedef struct unixInodeInfo unixInodeInfo;   /* An i-node */
--typedef struct UnixUnusedFd UnixUnusedFd;     /* An unused file descriptor */
-+static SQLITE_WSD struct sqlite3PrngType {
-+  unsigned char isInit;          /* True if initialized */
-+  unsigned char i, j;            /* State variables */
-+  unsigned char s[256];          /* State variables */
-+} sqlite3Prng;
- 
- /*
--** Sometimes, after a file handle is closed by SQLite, the file descriptor
--** cannot be closed immediately. In these cases, instances of the following
--** structure are used to store the file descriptor while waiting for an
--** opportunity to either close or reuse it.
-+** Get a single 8-bit random value from the RC4 PRNG.  The Mutex
-+** must be held while executing this routine.
-+**
-+** Why not just use a library random generator like lrand48() for this?
-+** Because the OP_NewRowid opcode in the VDBE depends on having a very
-+** good source of random numbers.  The lrand48() library function may
-+** well be good enough.  But maybe not.  Or maybe lrand48() has some
-+** subtle problems on some systems that could cause problems.  It is hard
-+** to know.  To minimize the risk of problems due to bad lrand48()
-+** implementations, SQLite uses this random number generator based
-+** on RC4, which we know works very well.
-+**
-+** (Later):  Actually, OP_NewRowid does not depend on a good source of
-+** randomness any more.  But we will leave this code in all the same.
- */
--struct UnixUnusedFd {
--  int fd;                   /* File descriptor to close */
--  int flags;                /* Flags this file descriptor was opened with */
--  UnixUnusedFd *pNext;      /* Next unused file descriptor on same file */
--};
-+static u8 randomByte(void){
-+  unsigned char t;
- 
--/*
--** The unixFile structure is subclass of sqlite3_file specific to the unix
--** VFS implementations.
--*/
--typedef struct unixFile unixFile;
--struct unixFile {
--  sqlite3_io_methods const *pMethod;  /* Always the first entry */
--  sqlite3_vfs *pVfs;                  /* The VFS that created this unixFile */
--  unixInodeInfo *pInode;              /* Info about locks on this inode */
--  int h;                              /* The file descriptor */
--  unsigned char eFileLock;            /* The type of lock held on this fd */
--  unsigned short int ctrlFlags;       /* Behavioral bits.  UNIXFILE_* flags */
--  int lastErrno;                      /* The unix errno from last I/O error */
--  void *lockingContext;               /* Locking style specific state */
--  UnixUnusedFd *pUnused;              /* Pre-allocated UnixUnusedFd */
--  const char *zPath;                  /* Name of the file */
--  unixShm *pShm;                      /* Shared memory segment information */
--  int szChunk;                        /* Configured by FCNTL_CHUNK_SIZE */
--  int nFetchOut;                      /* Number of outstanding xFetch refs */
--  sqlite3_int64 mmapSize;             /* Usable size of mapping at pMapRegion */
--  sqlite3_int64 mmapSizeActual;       /* Actual size of mapping at pMapRegion */
--  sqlite3_int64 mmapSizeMax;          /* Configured FCNTL_MMAP_SIZE value */
--  void *pMapRegion;                   /* Memory mapped region */
--#ifdef __QNXNTO__
--  int sectorSize;                     /* Device sector size */
--  int deviceCharacteristics;          /* Precomputed device characteristics */
--#endif
--#if SQLITE_ENABLE_LOCKING_STYLE
--  int openFlags;                      /* The flags specified at open() */
--#endif
--#if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__)
--  unsigned fsFlags;                   /* cached details from statfs() */
--#endif
--#if OS_VXWORKS
--  struct vxworksFileId *pId;          /* Unique file ID */
--#endif
--#ifdef SQLITE_DEBUG
--  /* The next group of variables are used to track whether or not the
--  ** transaction counter in bytes 24-27 of database files are updated
--  ** whenever any part of the database changes.  An assertion fault will
--  ** occur if a file is updated without also updating the transaction
--  ** counter.  This test is made to avoid new problems similar to the
--  ** one described by ticket #3584. 
--  */
--  unsigned char transCntrChng;   /* True if the transaction counter changed */
--  unsigned char dbUpdate;        /* True if any part of database file changed */
--  unsigned char inNormalWrite;   /* True if in a normal write operation */
- 
-+  /* The "wsdPrng" macro will resolve to the pseudo-random number generator
-+  ** 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, wsdPrng can refer directly
-+  ** to the "sqlite3Prng" state vector declared above.
-+  */
-+#ifdef SQLITE_OMIT_WSD
-+  struct sqlite3PrngType *p = &GLOBAL(struct sqlite3PrngType, sqlite3Prng);
-+# define wsdPrng p[0]
-+#else
-+# define wsdPrng sqlite3Prng
- #endif
- 
--#ifdef SQLITE_TEST
--  /* In test mode, increase the size of this structure a bit so that 
--  ** it is larger than the struct CrashFile defined in test6.c.
-+
-+  /* Initialize the state of the random number generator once,
-+  ** the first time this routine is called.  The seed value does
-+  ** not need to contain a lot of randomness since we are not
-+  ** trying to do secure encryption or anything like that...
-+  **
-+  ** Nothing in this file or anywhere else in SQLite does any kind of
-+  ** encryption.  The RC4 algorithm is being used as a PRNG (pseudo-random
-+  ** number generator) not as an encryption device.
-   */
--  char aPadding[32];
--#endif
--};
-+  if( !wsdPrng.isInit ){
-+    int i;
-+    char k[256];
-+    wsdPrng.j = 0;
-+    wsdPrng.i = 0;
-+    sqlite3OsRandomness(sqlite3_vfs_find(0), 256, k);
-+    for(i=0; i<256; i++){
-+      wsdPrng.s[i] = (u8)i;
-+    }
-+    for(i=0; i<256; i++){
-+      wsdPrng.j += wsdPrng.s[i] + k[i];
-+      t = wsdPrng.s[wsdPrng.j];
-+      wsdPrng.s[wsdPrng.j] = wsdPrng.s[i];
-+      wsdPrng.s[i] = t;
-+    }
-+    wsdPrng.isInit = 1;
-+  }
-+
-+  /* Generate and return single random byte
-+  */
-+  wsdPrng.i++;
-+  t = wsdPrng.s[wsdPrng.i];
-+  wsdPrng.j += t;
-+  wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j];
-+  wsdPrng.s[wsdPrng.j] = t;
-+  t += wsdPrng.s[wsdPrng.i];
-+  return wsdPrng.s[t];
-+}
- 
- /*
--** Allowed values for the unixFile.ctrlFlags bitmask:
-+** Return N random bytes.
- */
--#define UNIXFILE_EXCL        0x01     /* Connections from one process only */
--#define UNIXFILE_RDONLY      0x02     /* Connection is read only */
--#define UNIXFILE_PERSIST_WAL 0x04     /* Persistent WAL mode */
--#ifndef SQLITE_DISABLE_DIRSYNC
--# define UNIXFILE_DIRSYNC    0x08     /* Directory sync needed */
--#else
--# define UNIXFILE_DIRSYNC    0x00
-+SQLITE_API void sqlite3_randomness(int N, void *pBuf){
-+  unsigned char *zBuf = pBuf;
-+#if SQLITE_THREADSAFE
-+  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
- #endif
--#define UNIXFILE_PSOW        0x10     /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
--#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 */
-+  sqlite3_mutex_enter(mutex);
-+  while( N-- ){
-+    *(zBuf++) = randomByte();
-+  }
-+  sqlite3_mutex_leave(mutex);
-+}
- 
-+#ifndef SQLITE_OMIT_BUILTIN_TEST
- /*
--** Include code that is common to all os_*.c files
-+** For testing purposes, we sometimes want to preserve the state of
-+** PRNG and restore the PRNG to its saved state at a later time, or
-+** to reset the PRNG to its initial state.  These routines accomplish
-+** those tasks.
-+**
-+** The sqlite3_test_control() interface calls these routines to
-+** control the PRNG.
- */
--/************** Include os_common.h in the middle of os_unix.c ***************/
--/************** Begin file os_common.h ***************************************/
-+static SQLITE_WSD struct sqlite3PrngType sqlite3SavedPrng;
-+SQLITE_PRIVATE void sqlite3PrngSaveState(void){
-+  memcpy(
-+    &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng),
-+    &GLOBAL(struct sqlite3PrngType, sqlite3Prng),
-+    sizeof(sqlite3Prng)
-+  );
-+}
-+SQLITE_PRIVATE void sqlite3PrngRestoreState(void){
-+  memcpy(
-+    &GLOBAL(struct sqlite3PrngType, sqlite3Prng),
-+    &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng),
-+    sizeof(sqlite3Prng)
-+  );
-+}
-+SQLITE_PRIVATE void sqlite3PrngResetState(void){
-+  GLOBAL(struct sqlite3PrngType, sqlite3Prng).isInit = 0;
-+}
-+#endif /* SQLITE_OMIT_BUILTIN_TEST */
-+
-+/************** End of random.c **********************************************/
-+/************** Begin file utf.c *********************************************/
- /*
--** 2004 May 22
-+** 2004 April 13
- **
- ** The author disclaims copyright to this source code.  In place of
- ** a legal notice, here is a blessing:
-@@ -23182,13485 +23716,14956 @@
- **    May you find forgiveness for yourself and forgive others.
- **    May you share freely, never taking more than you give.
- **
--******************************************************************************
-+*************************************************************************
-+** This file contains routines used to translate between UTF-8, 
-+** UTF-16, UTF-16BE, and UTF-16LE.
- **
--** This file contains macros and a little bit of code that is common to
--** all of the platform-specific files (os_*.c) and is #included into those
--** files.
-+** Notes on UTF-8:
-+**
-+**   Byte-0    Byte-1    Byte-2    Byte-3    Value
-+**  0xxxxxxx                                 00000000 00000000 0xxxxxxx
-+**  110yyyyy  10xxxxxx                       00000000 00000yyy yyxxxxxx
-+**  1110zzzz  10yyyyyy  10xxxxxx             00000000 zzzzyyyy yyxxxxxx
-+**  11110uuu  10uuzzzz  10yyyyyy  10xxxxxx   000uuuuu zzzzyyyy yyxxxxxx
-+**
-+**
-+** Notes on UTF-16:  (with wwww+1==uuuuu)
-+**
-+**      Word-0               Word-1          Value
-+**  110110ww wwzzzzyy   110111yy yyxxxxxx    000uuuuu zzzzyyyy yyxxxxxx
-+**  zzzzyyyy yyxxxxxx                        00000000 zzzzyyyy yyxxxxxx
-+**
-+**
-+** BOM or Byte Order Mark:
-+**     0xff 0xfe   little-endian utf-16 follows
-+**     0xfe 0xff   big-endian utf-16 follows
- **
--** This file should be #included by the os_*.c files only.  It is not a
--** general purpose header file.
- */
--#ifndef _OS_COMMON_H_
--#define _OS_COMMON_H_
-+/* #include <assert.h> */
- 
-+#ifndef SQLITE_AMALGAMATION
- /*
--** At least two bugs have slipped in because we changed the MEMORY_DEBUG
--** macro to SQLITE_DEBUG and some older makefiles have not yet made the
--** switch.  The following code should catch this problem at compile-time.
-+** The following constant value is used by the SQLITE_BIGENDIAN and
-+** SQLITE_LITTLEENDIAN macros.
- */
--#ifdef MEMORY_DEBUG
--# 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
-+SQLITE_PRIVATE const int sqlite3one = 1;
-+#endif /* SQLITE_AMALGAMATION */
- 
- /*
--** Macros for performance tracing.  Normally turned off.  Only works
--** on i486 hardware.
-+** This lookup table is used to help decode the first byte of
-+** a multi-byte UTF8 character.
- */
--#ifdef SQLITE_PERFORMANCE_TRACE
-+static const unsigned char sqlite3Utf8Trans1[] = {
-+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-+  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-+  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-+  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-+  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-+  0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00,
-+};
-+
-+
-+#define WRITE_UTF8(zOut, c) {                          \
-+  if( c<0x00080 ){                                     \
-+    *zOut++ = (u8)(c&0xFF);                            \
-+  }                                                    \
-+  else if( c<0x00800 ){                                \
-+    *zOut++ = 0xC0 + (u8)((c>>6)&0x1F);                \
-+    *zOut++ = 0x80 + (u8)(c & 0x3F);                   \
-+  }                                                    \
-+  else if( c<0x10000 ){                                \
-+    *zOut++ = 0xE0 + (u8)((c>>12)&0x0F);               \
-+    *zOut++ = 0x80 + (u8)((c>>6) & 0x3F);              \
-+    *zOut++ = 0x80 + (u8)(c & 0x3F);                   \
-+  }else{                                               \
-+    *zOut++ = 0xF0 + (u8)((c>>18) & 0x07);             \
-+    *zOut++ = 0x80 + (u8)((c>>12) & 0x3F);             \
-+    *zOut++ = 0x80 + (u8)((c>>6) & 0x3F);              \
-+    *zOut++ = 0x80 + (u8)(c & 0x3F);                   \
-+  }                                                    \
-+}
-+
-+#define WRITE_UTF16LE(zOut, c) {                                    \
-+  if( c<=0xFFFF ){                                                  \
-+    *zOut++ = (u8)(c&0x00FF);                                       \
-+    *zOut++ = (u8)((c>>8)&0x00FF);                                  \
-+  }else{                                                            \
-+    *zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0));  \
-+    *zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03));              \
-+    *zOut++ = (u8)(c&0x00FF);                                       \
-+    *zOut++ = (u8)(0x00DC + ((c>>8)&0x03));                         \
-+  }                                                                 \
-+}
-+
-+#define WRITE_UTF16BE(zOut, c) {                                    \
-+  if( c<=0xFFFF ){                                                  \
-+    *zOut++ = (u8)((c>>8)&0x00FF);                                  \
-+    *zOut++ = (u8)(c&0x00FF);                                       \
-+  }else{                                                            \
-+    *zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03));              \
-+    *zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0));  \
-+    *zOut++ = (u8)(0x00DC + ((c>>8)&0x03));                         \
-+    *zOut++ = (u8)(c&0x00FF);                                       \
-+  }                                                                 \
-+}
-+
-+#define READ_UTF16LE(zIn, TERM, c){                                   \
-+  c = (*zIn++);                                                       \
-+  c += ((*zIn++)<<8);                                                 \
-+  if( c>=0xD800 && c<0xE000 && TERM ){                                \
-+    int c2 = (*zIn++);                                                \
-+    c2 += ((*zIn++)<<8);                                              \
-+    c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10);   \
-+  }                                                                   \
-+}
-+
-+#define READ_UTF16BE(zIn, TERM, c){                                   \
-+  c = ((*zIn++)<<8);                                                  \
-+  c += (*zIn++);                                                      \
-+  if( c>=0xD800 && c<0xE000 && TERM ){                                \
-+    int c2 = ((*zIn++)<<8);                                           \
-+    c2 += (*zIn++);                                                   \
-+    c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10);   \
-+  }                                                                   \
-+}
- 
--/* 
--** hwtime.h contains inline assembler code for implementing 
--** high-performance timing routines.
--*/
--/************** Include hwtime.h in the middle of os_common.h ****************/
--/************** Begin file hwtime.h ******************************************/
- /*
--** 2008 May 27
-+** Translate a single UTF-8 character.  Return the unicode value.
- **
--** The author disclaims copyright to this source code.  In place of
--** a legal notice, here is a blessing:
-+** During translation, assume that the byte that zTerm points
-+** is a 0x00.
- **
--**    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.
-+** Write a pointer to the next unread byte back into *pzNext.
- **
--******************************************************************************
-+** Notes On Invalid UTF-8:
- **
--** This file contains inline asm code for retrieving "high-performance"
--** counters for x86 class CPUs.
-+**  *  This routine never allows a 7-bit character (0x00 through 0x7f) to
-+**     be encoded as a multi-byte character.  Any multi-byte character that
-+**     attempts to encode a value between 0x00 and 0x7f is rendered as 0xfffd.
-+**
-+**  *  This routine never allows a UTF16 surrogate value to be encoded.
-+**     If a multi-byte character attempts to encode a value between
-+**     0xd800 and 0xe000 then it is rendered as 0xfffd.
-+**
-+**  *  Bytes in the range of 0x80 through 0xbf which occur as the first
-+**     byte of a character are interpreted as single-byte characters
-+**     and rendered as themselves even though they are technically
-+**     invalid characters.
-+**
-+**  *  This routine accepts an infinite number of different UTF8 encodings
-+**     for unicode values 0x80 and greater.  It do not change over-length
-+**     encodings to 0xfffd as some systems recommend.
- */
--#ifndef _HWTIME_H_
--#define _HWTIME_H_
-+#define READ_UTF8(zIn, zTerm, c)                           \
-+  c = *(zIn++);                                            \
-+  if( c>=0xc0 ){                                           \
-+    c = sqlite3Utf8Trans1[c-0xc0];                         \
-+    while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){            \
-+      c = (c<<6) + (0x3f & *(zIn++));                      \
-+    }                                                      \
-+    if( c<0x80                                             \
-+        || (c&0xFFFFF800)==0xD800                          \
-+        || (c&0xFFFFFFFE)==0xFFFE ){  c = 0xFFFD; }        \
-+  }
-+SQLITE_PRIVATE u32 sqlite3Utf8Read(
-+  const unsigned char **pz    /* Pointer to string from which to read char */
-+){
-+  unsigned int c;
-+
-+  /* Same as READ_UTF8() above but without the zTerm parameter.
-+  ** For this routine, we assume the UTF8 string is always zero-terminated.
-+  */
-+  c = *((*pz)++);
-+  if( c>=0xc0 ){
-+    c = sqlite3Utf8Trans1[c-0xc0];
-+    while( (*(*pz) & 0xc0)==0x80 ){
-+      c = (c<<6) + (0x3f & *((*pz)++));
-+    }
-+    if( c<0x80
-+        || (c&0xFFFFF800)==0xD800
-+        || (c&0xFFFFFFFE)==0xFFFE ){  c = 0xFFFD; }
-+  }
-+  return c;
-+}
-+
-+
-+
- 
- /*
--** The following routine only works on pentium-class (or newer) processors.
--** It uses the RDTSC opcode to read the cycle count value out of the
--** processor and returns that value.  This can be used for high-res
--** profiling.
-+** If the TRANSLATE_TRACE macro is defined, the value of each Mem is
-+** printed on stderr on the way into and out of sqlite3VdbeMemTranslate().
-+*/ 
-+/* #define TRANSLATE_TRACE 1 */
-+
-+#ifndef SQLITE_OMIT_UTF16
-+/*
-+** This routine transforms the internal text encoding used by pMem to
-+** desiredEnc. It is an error if the string is already of the desired
-+** encoding, or if *pMem does not contain a string value.
- */
--#if (defined(__GNUC__) || defined(_MSC_VER)) && \
--      (defined(i386) || defined(__i386__) || defined(_M_IX86))
-+SQLITE_PRIVATE 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 */
-+  unsigned char *zTerm;                 /* End of input */
-+  unsigned char *z;                     /* Output iterator */
-+  unsigned int c;
- 
--  #if defined(__GNUC__)
-+  assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
-+  assert( pMem->flags&MEM_Str );
-+  assert( pMem->enc!=desiredEnc );
-+  assert( pMem->enc!=0 );
-+  assert( pMem->n>=0 );
- 
--  __inline__ sqlite_uint64 sqlite3Hwtime(void){
--     unsigned int lo, hi;
--     __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
--     return (sqlite_uint64)hi << 32 | lo;
-+#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
-+  {
-+    char zBuf[100];
-+    sqlite3VdbeMemPrettyPrint(pMem, zBuf);
-+    fprintf(stderr, "INPUT:  %s\n", zBuf);
-   }
-+#endif
- 
--  #elif defined(_MSC_VER)
--
--  __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
--     __asm {
--        rdtsc
--        ret       ; return value at EDX:EAX
--     }
-+  /* If the translation is between UTF-16 little and big endian, then 
-+  ** all that is required is to swap the byte order. This case is handled
-+  ** differently from the others.
-+  */
-+  if( pMem->enc!=SQLITE_UTF8 && desiredEnc!=SQLITE_UTF8 ){
-+    u8 temp;
-+    int rc;
-+    rc = sqlite3VdbeMemMakeWriteable(pMem);
-+    if( rc!=SQLITE_OK ){
-+      assert( rc==SQLITE_NOMEM );
-+      return SQLITE_NOMEM;
-+    }
-+    zIn = (u8*)pMem->z;
-+    zTerm = &zIn[pMem->n&~1];
-+    while( zIn<zTerm ){
-+      temp = *zIn;
-+      *zIn = *(zIn+1);
-+      zIn++;
-+      *zIn++ = temp;
-+    }
-+    pMem->enc = desiredEnc;
-+    goto translate_out;
-   }
- 
--  #endif
--
--#elif (defined(__GNUC__) && defined(__x86_64__))
-+  /* Set len to the maximum number of bytes required in the output buffer. */
-+  if( desiredEnc==SQLITE_UTF8 ){
-+    /* When converting from UTF-16, the maximum growth results from
-+    ** translating a 2-byte character to a 4-byte UTF-8 character.
-+    ** A single byte is required for the output string
-+    ** nul-terminator.
-+    */
-+    pMem->n &= ~1;
-+    len = pMem->n * 2 + 1;
-+  }else{
-+    /* When converting from UTF-8 to UTF-16 the maximum growth is caused
-+    ** when a 1-byte UTF-8 character is translated into a 2-byte UTF-16
-+    ** character. Two bytes are required in the output buffer for the
-+    ** nul-terminator.
-+    */
-+    len = pMem->n * 2 + 2;
-+  }
- 
--  __inline__ sqlite_uint64 sqlite3Hwtime(void){
--      unsigned long val;
--      __asm__ __volatile__ ("rdtsc" : "=A" (val));
--      return val;
-+  /* Set zIn to point at the start of the input buffer and zTerm to point 1
-+  ** byte past the end.
-+  **
-+  ** Variable zOut is set to point at the output buffer, space obtained
-+  ** from sqlite3_malloc().
-+  */
-+  zIn = (u8*)pMem->z;
-+  zTerm = &zIn[pMem->n];
-+  zOut = sqlite3DbMallocRaw(pMem->db, len);
-+  if( !zOut ){
-+    return SQLITE_NOMEM;
-   }
-- 
--#elif (defined(__GNUC__) && defined(__ppc__))
-+  z = zOut;
- 
--  __inline__ sqlite_uint64 sqlite3Hwtime(void){
--      unsigned long long retval;
--      unsigned long junk;
--      __asm__ __volatile__ ("\n\
--          1:      mftbu   %1\n\
--                  mftb    %L0\n\
--                  mftbu   %0\n\
--                  cmpw    %0,%1\n\
--                  bne     1b"
--                  : "=r" (retval), "=r" (junk));
--      return retval;
-+  if( pMem->enc==SQLITE_UTF8 ){
-+    if( desiredEnc==SQLITE_UTF16LE ){
-+      /* UTF-8 -> UTF-16 Little-endian */
-+      while( zIn<zTerm ){
-+        READ_UTF8(zIn, zTerm, c);
-+        WRITE_UTF16LE(z, c);
-+      }
-+    }else{
-+      assert( desiredEnc==SQLITE_UTF16BE );
-+      /* UTF-8 -> UTF-16 Big-endian */
-+      while( zIn<zTerm ){
-+        READ_UTF8(zIn, zTerm, c);
-+        WRITE_UTF16BE(z, c);
-+      }
-+    }
-+    pMem->n = (int)(z - zOut);
-+    *z++ = 0;
-+  }else{
-+    assert( desiredEnc==SQLITE_UTF8 );
-+    if( pMem->enc==SQLITE_UTF16LE ){
-+      /* UTF-16 Little-endian -> UTF-8 */
-+      while( zIn<zTerm ){
-+        READ_UTF16LE(zIn, zIn<zTerm, c); 
-+        WRITE_UTF8(z, c);
-+      }
-+    }else{
-+      /* UTF-16 Big-endian -> UTF-8 */
-+      while( zIn<zTerm ){
-+        READ_UTF16BE(zIn, zIn<zTerm, c); 
-+        WRITE_UTF8(z, c);
-+      }
-+    }
-+    pMem->n = (int)(z - zOut);
-   }
-+  *z = 0;
-+  assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len );
- 
--#else
-+  sqlite3VdbeMemRelease(pMem);
-+  pMem->flags &= ~(MEM_Static|MEM_Dyn|MEM_Ephem);
-+  pMem->enc = desiredEnc;
-+  pMem->flags |= (MEM_Term|MEM_Dyn);
-+  pMem->z = (char*)zOut;
-+  pMem->zMalloc = pMem->z;
- 
--  #error Need implementation of sqlite3Hwtime() for your platform.
-+translate_out:
-+#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
-+  {
-+    char zBuf[100];
-+    sqlite3VdbeMemPrettyPrint(pMem, zBuf);
-+    fprintf(stderr, "OUTPUT: %s\n", zBuf);
-+  }
-+#endif
-+  return SQLITE_OK;
-+}
- 
--  /*
--  ** To compile without implementing sqlite3Hwtime() for your platform,
--  ** you can remove the above #error and use the following
--  ** stub function.  You will lose timing support for many
--  ** of the debugging and testing utilities, but it should at
--  ** least compile and run.
--  */
--SQLITE_PRIVATE   sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
-+/*
-+** This routine checks for a byte-order mark at the beginning of the 
-+** UTF-16 string stored in *pMem. If one is present, it is removed and
-+** the encoding of the Mem adjusted. This routine does not do any
-+** byte-swapping, it just sets Mem.enc appropriately.
-+**
-+** The allocation (static, dynamic etc.) and encoding of the Mem may be
-+** changed by this function.
-+*/
-+SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem){
-+  int rc = SQLITE_OK;
-+  u8 bom = 0;
- 
--#endif
-+  assert( pMem->n>=0 );
-+  if( pMem->n>1 ){
-+    u8 b1 = *(u8 *)pMem->z;
-+    u8 b2 = *(((u8 *)pMem->z) + 1);
-+    if( b1==0xFE && b2==0xFF ){
-+      bom = SQLITE_UTF16BE;
-+    }
-+    if( b1==0xFF && b2==0xFE ){
-+      bom = SQLITE_UTF16LE;
-+    }
-+  }
-+  
-+  if( bom ){
-+    rc = sqlite3VdbeMemMakeWriteable(pMem);
-+    if( rc==SQLITE_OK ){
-+      pMem->n -= 2;
-+      memmove(pMem->z, &pMem->z[2], pMem->n);
-+      pMem->z[pMem->n] = '\0';
-+      pMem->z[pMem->n+1] = '\0';
-+      pMem->flags |= MEM_Term;
-+      pMem->enc = bom;
-+    }
-+  }
-+  return rc;
-+}
-+#endif /* SQLITE_OMIT_UTF16 */
- 
--#endif /* !defined(_HWTIME_H_) */
-+/*
-+** pZ is a UTF-8 encoded unicode string. If nByte is less than zero,
-+** return the number of unicode characters in pZ up to (but not including)
-+** the first 0x00 byte. If nByte is not less than zero, return the
-+** number of unicode characters in the first nByte of pZ (or up to 
-+** the first 0x00, whichever comes first).
-+*/
-+SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *zIn, int nByte){
-+  int r = 0;
-+  const u8 *z = (const u8*)zIn;
-+  const u8 *zTerm;
-+  if( nByte>=0 ){
-+    zTerm = &z[nByte];
-+  }else{
-+    zTerm = (const u8*)(-1);
-+  }
-+  assert( z<=zTerm );
-+  while( *z!=0 && z<zTerm ){
-+    SQLITE_SKIP_UTF8(z);
-+    r++;
-+  }
-+  return r;
-+}
- 
--/************** End of hwtime.h **********************************************/
--/************** Continuing where we left off in os_common.h ******************/
-+/* This test function is not currently used by the automated test-suite. 
-+** Hence it is only available in debug builds.
-+*/
-+#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
-+/*
-+** Translate UTF-8 to UTF-8.
-+**
-+** This has the effect of making sure that the string is well-formed
-+** UTF-8.  Miscoded characters are removed.
-+**
-+** The translation is done in-place and aborted if the output
-+** overruns the input.
-+*/
-+SQLITE_PRIVATE int sqlite3Utf8To8(unsigned char *zIn){
-+  unsigned char *zOut = zIn;
-+  unsigned char *zStart = zIn;
-+  u32 c;
- 
--static sqlite_uint64 g_start;
--static sqlite_uint64 g_elapsed;
--#define TIMER_START       g_start=sqlite3Hwtime()
--#define TIMER_END         g_elapsed=sqlite3Hwtime()-g_start
--#define TIMER_ELAPSED     g_elapsed
--#else
--#define TIMER_START
--#define TIMER_END
--#define TIMER_ELAPSED     ((sqlite_uint64)0)
-+  while( zIn[0] && zOut<=zIn ){
-+    c = sqlite3Utf8Read((const u8**)&zIn);
-+    if( c!=0xfffd ){
-+      WRITE_UTF8(zOut, c);
-+    }
-+  }
-+  *zOut = 0;
-+  return (int)(zOut - zStart);
-+}
- #endif
- 
-+#ifndef SQLITE_OMIT_UTF16
- /*
--** If we compile with the SQLITE_TEST macro set, then the following block
--** of code will give us the ability to simulate a disk I/O error.  This
--** is used for testing the I/O recovery logic.
-+** Convert a UTF-16 string in the native encoding into a UTF-8 string.
-+** Memory to hold the UTF-8 string is obtained from sqlite3_malloc and must
-+** be freed by the calling function.
-+**
-+** NULL is returned if there is an allocation error.
- */
--#ifdef SQLITE_TEST
--SQLITE_API int sqlite3_io_error_hit = 0;            /* Total number of I/O Errors */
--SQLITE_API int sqlite3_io_error_hardhit = 0;        /* Number of non-benign errors */
--SQLITE_API int sqlite3_io_error_pending = 0;        /* Count down to first I/O error */
--SQLITE_API int sqlite3_io_error_persist = 0;        /* True if I/O errors persist */
--SQLITE_API int sqlite3_io_error_benign = 0;         /* True if errors are benign */
--SQLITE_API int sqlite3_diskfull_pending = 0;
--SQLITE_API int sqlite3_diskfull = 0;
--#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X)
--#define SimulateIOError(CODE)  \
--  if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \
--       || sqlite3_io_error_pending-- == 1 )  \
--              { local_ioerr(); CODE; }
--static void local_ioerr(){
--  IOTRACE(("IOERR\n"));
--  sqlite3_io_error_hit++;
--  if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++;
-+SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *db, const void *z, int nByte, u8 enc){
-+  Mem m;
-+  memset(&m, 0, sizeof(m));
-+  m.db = db;
-+  sqlite3VdbeMemSetStr(&m, z, nByte, enc, SQLITE_STATIC);
-+  sqlite3VdbeChangeEncoding(&m, SQLITE_UTF8);
-+  if( db->mallocFailed ){
-+    sqlite3VdbeMemRelease(&m);
-+    m.z = 0;
-+  }
-+  assert( (m.flags & MEM_Term)!=0 || db->mallocFailed );
-+  assert( (m.flags & MEM_Str)!=0 || db->mallocFailed );
-+  assert( (m.flags & MEM_Dyn)!=0 || db->mallocFailed );
-+  assert( m.z || db->mallocFailed );
-+  return m.z;
-+}
-+
-+/*
-+** Convert a UTF-8 string to the UTF-16 encoding specified by parameter
-+** enc. A pointer to the new string is returned, and the value of *pnOut
-+** is set to the length of the returned string in bytes. The call should
-+** arrange to call sqlite3DbFree() on the returned pointer when it is
-+** no longer required.
-+** 
-+** If a malloc failure occurs, NULL is returned and the db.mallocFailed
-+** flag set.
-+*/
-+#ifdef SQLITE_ENABLE_STAT3
-+SQLITE_PRIVATE char *sqlite3Utf8to16(sqlite3 *db, u8 enc, char *z, int n, int *pnOut){
-+  Mem m;
-+  memset(&m, 0, sizeof(m));
-+  m.db = db;
-+  sqlite3VdbeMemSetStr(&m, z, n, SQLITE_UTF8, SQLITE_STATIC);
-+  if( sqlite3VdbeMemTranslate(&m, enc) ){
-+    assert( db->mallocFailed );
-+    return 0;
-+  }
-+  assert( m.z==m.zMalloc );
-+  *pnOut = m.n;
-+  return m.z;
- }
--#define SimulateDiskfullError(CODE) \
--   if( sqlite3_diskfull_pending ){ \
--     if( sqlite3_diskfull_pending == 1 ){ \
--       local_ioerr(); \
--       sqlite3_diskfull = 1; \
--       sqlite3_io_error_hit = 1; \
--       CODE; \
--     }else{ \
--       sqlite3_diskfull_pending--; \
--     } \
--   }
--#else
--#define SimulateIOErrorBenign(X)
--#define SimulateIOError(A)
--#define SimulateDiskfullError(A)
- #endif
- 
- /*
--** When testing, keep a count of the number of open files.
-+** zIn is a UTF-16 encoded unicode string at least nChar characters long.
-+** Return the number of bytes in the first nChar unicode characters
-+** in pZ.  nChar must be non-negative.
-+*/
-+SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *zIn, int nChar){
-+  int c;
-+  unsigned char const *z = zIn;
-+  int n = 0;
-+  
-+  if( SQLITE_UTF16NATIVE==SQLITE_UTF16BE ){
-+    while( n<nChar ){
-+      READ_UTF16BE(z, 1, c);
-+      n++;
-+    }
-+  }else{
-+    while( n<nChar ){
-+      READ_UTF16LE(z, 1, c);
-+      n++;
-+    }
-+  }
-+  return (int)(z-(unsigned char const *)zIn);
-+}
-+
-+#if defined(SQLITE_TEST)
-+/*
-+** This routine is called from the TCL test function "translate_selftest".
-+** It checks that the primitives for serializing and deserializing
-+** characters in each encoding are inverses of each other.
-+*/
-+SQLITE_PRIVATE void sqlite3UtfSelfTest(void){
-+  unsigned int i, t;
-+  unsigned char zBuf[20];
-+  unsigned char *z;
-+  int n;
-+  unsigned int c;
-+
-+  for(i=0; i<0x00110000; i++){
-+    z = zBuf;
-+    WRITE_UTF8(z, i);
-+    n = (int)(z-zBuf);
-+    assert( n>0 && n<=4 );
-+    z[0] = 0;
-+    z = zBuf;
-+    c = sqlite3Utf8Read((const u8**)&z);
-+    t = i;
-+    if( i>=0xD800 && i<=0xDFFF ) t = 0xFFFD;
-+    if( (i&0xFFFFFFFE)==0xFFFE ) t = 0xFFFD;
-+    assert( c==t );
-+    assert( (z-zBuf)==n );
-+  }
-+  for(i=0; i<0x00110000; i++){
-+    if( i>=0xD800 && i<0xE000 ) continue;
-+    z = zBuf;
-+    WRITE_UTF16LE(z, i);
-+    n = (int)(z-zBuf);
-+    assert( n>0 && n<=4 );
-+    z[0] = 0;
-+    z = zBuf;
-+    READ_UTF16LE(z, 1, c);
-+    assert( c==i );
-+    assert( (z-zBuf)==n );
-+  }
-+  for(i=0; i<0x00110000; i++){
-+    if( i>=0xD800 && i<0xE000 ) continue;
-+    z = zBuf;
-+    WRITE_UTF16BE(z, i);
-+    n = (int)(z-zBuf);
-+    assert( n>0 && n<=4 );
-+    z[0] = 0;
-+    z = zBuf;
-+    READ_UTF16BE(z, 1, c);
-+    assert( c==i );
-+    assert( (z-zBuf)==n );
-+  }
-+}
-+#endif /* SQLITE_TEST */
-+#endif /* SQLITE_OMIT_UTF16 */
-+
-+/************** End of utf.c *************************************************/
-+/************** Begin file util.c ********************************************/
-+/*
-+** 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.
-+**
-+*************************************************************************
-+** Utility functions used throughout sqlite.
-+**
-+** This file contains functions for allocating memory, comparing
-+** strings, and stuff like that.
-+**
- */
--#ifdef SQLITE_TEST
--SQLITE_API int sqlite3_open_file_count = 0;
--#define OpenCounter(X)  sqlite3_open_file_count+=(X)
--#else
--#define OpenCounter(X)
-+/* #include <stdarg.h> */
-+#ifdef SQLITE_HAVE_ISNAN
-+# include <math.h>
- #endif
- 
--#endif /* !defined(_OS_COMMON_H_) */
--
--/************** End of os_common.h *******************************************/
--/************** Continuing where we left off in os_unix.c ********************/
--
- /*
--** Define various macros that are missing from some systems.
-+** Routine needed to support the testcase() macro.
- */
--#ifndef O_LARGEFILE
--# define O_LARGEFILE 0
--#endif
--#ifdef SQLITE_DISABLE_LFS
--# undef O_LARGEFILE
--# define O_LARGEFILE 0
--#endif
--#ifndef O_NOFOLLOW
--# define O_NOFOLLOW 0
--#endif
--#ifndef O_BINARY
--# define O_BINARY 0
-+#ifdef SQLITE_COVERAGE_TEST
-+SQLITE_PRIVATE void sqlite3Coverage(int x){
-+  static unsigned dummy = 0;
-+  dummy += (unsigned)x;
-+}
- #endif
- 
-+#ifndef SQLITE_OMIT_FLOATING_POINT
- /*
--** The threadid macro resolves to the thread-id or to 0.  Used for
--** testing and debugging only.
-+** Return true if the floating point value is Not a Number (NaN).
-+**
-+** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN.
-+** Otherwise, we have our own implementation that works on most systems.
- */
--#if SQLITE_THREADSAFE
--#define threadid pthread_self()
--#else
--#define threadid 0
-+SQLITE_PRIVATE int sqlite3IsNaN(double x){
-+  int rc;   /* The value return */
-+#if !defined(SQLITE_HAVE_ISNAN)
-+  /*
-+  ** Systems that support the isnan() library function should probably
-+  ** make use of it by compiling with -DSQLITE_HAVE_ISNAN.  But we have
-+  ** found that many systems do not have a working isnan() function so
-+  ** this implementation is provided as an alternative.
-+  **
-+  ** This NaN test sometimes fails if compiled on GCC with -ffast-math.
-+  ** On the other hand, the use of -ffast-math comes with the following
-+  ** warning:
-+  **
-+  **      This option [-ffast-math] should never be turned on by any
-+  **      -O option since it can result in incorrect output for programs
-+  **      which depend on an exact implementation of IEEE or ISO 
-+  **      rules/specifications for math functions.
-+  **
-+  ** Under MSVC, this NaN test may fail if compiled with a floating-
-+  ** point precision mode other than /fp:precise.  From the MSDN 
-+  ** documentation:
-+  **
-+  **      The compiler [with /fp:precise] will properly handle comparisons 
-+  **      involving NaN. For example, x != x evaluates to true if x is NaN 
-+  **      ...
-+  */
-+#ifdef __FAST_MATH__
-+# error SQLite will not work correctly with the -ffast-math option of GCC.
- #endif
-+  volatile double y = x;
-+  volatile double z = y;
-+  rc = (y!=z);
-+#else  /* if defined(SQLITE_HAVE_ISNAN) */
-+  rc = isnan(x);
-+#endif /* SQLITE_HAVE_ISNAN */
-+  testcase( rc );
-+  return rc;
-+}
-+#endif /* SQLITE_OMIT_FLOATING_POINT */
- 
- /*
--** HAVE_MREMAP defaults to true on Linux and false everywhere else.
-+** Compute a string length that is limited to what can be stored in
-+** lower 30 bits of a 32-bit signed integer.
-+**
-+** The value returned will never be negative.  Nor will it ever be greater
-+** than the actual length of the string.  For very long strings (greater
-+** than 1GiB) the value returned might be less than the true string length.
- */
--#if !defined(HAVE_MREMAP)
--# if defined(__linux__) && defined(_GNU_SOURCE)
--#  define HAVE_MREMAP 1
--# else
--#  define HAVE_MREMAP 0
--# endif
--#endif
-+SQLITE_PRIVATE int sqlite3Strlen30(const char *z){
-+  const char *z2 = z;
-+  if( z==0 ) return 0;
-+  while( *z2 ){ z2++; }
-+  return 0x3fffffff & (int)(z2 - z);
-+}
- 
- /*
--** 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.
-+** Set the most recent error code and error string for the sqlite
-+** handle "db". The error code is set to "err_code".
- **
--** The safest way to deal with the problem is to always use this wrapper
--** which always has the same well-defined interface.
-+** If it is not NULL, string zFormat specifies the format of the
-+** error string in the style of the printf functions: The following
-+** format characters are allowed:
-+**
-+**      %s      Insert a string
-+**      %z      A string that should be freed after use
-+**      %d      Insert an integer
-+**      %T      Insert a token
-+**      %S      Insert the first element of a SrcList
-+**
-+** zFormat and any string tokens that follow it are assumed to be
-+** encoded in UTF-8.
-+**
-+** To clear the most recent error for sqlite handle "db", sqlite3Error
-+** should be called with err_code set to SQLITE_OK and zFormat set
-+** to NULL.
- */
--static int posixOpen(const char *zFile, int flags, int mode){
--  return open(zFile, flags, mode);
-+SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat, ...){
-+  if( db && (db->pErr || (db->pErr = sqlite3ValueNew(db))!=0) ){
-+    db->errCode = err_code;
-+    if( zFormat ){
-+      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{
-+      sqlite3ValueSetStr(db->pErr, 0, 0, SQLITE_UTF8, SQLITE_STATIC);
-+    }
-+  }
- }
- 
- /*
--** On some systems, calls to fchown() will trigger a message in a security
--** log if they come from non-root processes.  So avoid calling fchown() if
--** we are not running as root.
-+** Add an error message to pParse->zErrMsg and increment pParse->nErr.
-+** The following formatting characters are allowed:
-+**
-+**      %s      Insert a string
-+**      %z      A string that should be freed after use
-+**      %d      Insert an integer
-+**      %T      Insert a token
-+**      %S      Insert the first element of a SrcList
-+**
-+** This function should be used to report any error that occurs whilst
-+** 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.).
- */
--static int posixFchown(int fd, uid_t uid, gid_t gid){
--  return geteuid() ? 0 : fchown(fd,uid,gid);
-+SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
-+  char *zMsg;
-+  va_list ap;
-+  sqlite3 *db = pParse->db;
-+  va_start(ap, zFormat);
-+  zMsg = sqlite3VMPrintf(db, zFormat, ap);
-+  va_end(ap);
-+  if( db->suppressErr ){
-+    sqlite3DbFree(db, zMsg);
-+  }else{
-+    pParse->nErr++;
-+    sqlite3DbFree(db, pParse->zErrMsg);
-+    pParse->zErrMsg = zMsg;
-+    pParse->rc = SQLITE_ERROR;
-+  }
- }
- 
--/* Forward reference */
--static int openDirectory(const char*, int*);
--
- /*
--** Many system calls are accessed through pointer-to-functions so that
--** they may be overridden at runtime to facilitate fault injection during
--** testing and sandboxing.  The following array holds the names and pointers
--** to all overrideable system calls.
-+** Convert an SQL-style quoted string into a normal string by removing
-+** the quote characters.  The conversion is done in-place.  If the
-+** input does not begin with a quote character, then this routine
-+** is a no-op.
-+**
-+** The input string must be zero-terminated.  A new zero-terminator
-+** is added to the dequoted string.
-+**
-+** The return value is -1 if no dequoting occurs or the length of the
-+** dequoted string, exclusive of the zero terminator, if dequoting does
-+** occur.
-+**
-+** 2002-Feb-14: This routine is extended to remove MS-Access style
-+** brackets from around identifers.  For example:  "[a-b-c]" becomes
-+** "a-b-c".
- */
--static struct unix_syscall {
--  const char *zName;            /* Name of the system call */
--  sqlite3_syscall_ptr pCurrent; /* Current value of the system call */
--  sqlite3_syscall_ptr pDefault; /* Default value */
--} aSyscall[] = {
--  { "open",         (sqlite3_syscall_ptr)posixOpen,  0  },
--#define osOpen      ((int(*)(const char*,int,int))aSyscall[0].pCurrent)
--
--  { "close",        (sqlite3_syscall_ptr)close,      0  },
--#define osClose     ((int(*)(int))aSyscall[1].pCurrent)
--
--  { "access",       (sqlite3_syscall_ptr)access,     0  },
--#define osAccess    ((int(*)(const char*,int))aSyscall[2].pCurrent)
--
--  { "getcwd",       (sqlite3_syscall_ptr)getcwd,     0  },
--#define osGetcwd    ((char*(*)(char*,size_t))aSyscall[3].pCurrent)
-+SQLITE_PRIVATE int sqlite3Dequote(char *z){
-+  char quote;
-+  int i, j;
-+  if( z==0 ) return -1;
-+  quote = z[0];
-+  switch( quote ){
-+    case '\'':  break;
-+    case '"':   break;
-+    case '`':   break;                /* For MySQL compatibility */
-+    case '[':   quote = ']';  break;  /* For MS SqlServer compatibility */
-+    default:    return -1;
-+  }
-+  for(i=1, j=0; ALWAYS(z[i]); i++){
-+    if( z[i]==quote ){
-+      if( z[i+1]==quote ){
-+        z[j++] = quote;
-+        i++;
-+      }else{
-+        break;
-+      }
-+    }else{
-+      z[j++] = z[i];
-+    }
-+  }
-+  z[j] = 0;
-+  return j;
-+}
- 
--  { "stat",         (sqlite3_syscall_ptr)stat,       0  },
--#define osStat      ((int(*)(const char*,struct stat*))aSyscall[4].pCurrent)
-+/* Convenient short-hand */
-+#define UpperToLower sqlite3UpperToLower
- 
- /*
--** The DJGPP compiler environment looks mostly like Unix, but it
--** lacks the fcntl() system call.  So redefine fcntl() to be something
--** that always succeeds.  This means that locking does not occur under
--** DJGPP.  But it is DOS - what did you expect?
-+** Some systems have stricmp().  Others have strcasecmp().  Because
-+** there is no consistency, we will define our own.
-+**
-+** IMPLEMENTATION-OF: R-30243-02494 The sqlite3_stricmp() and
-+** sqlite3_strnicmp() APIs allow applications and extensions to compare
-+** the contents of two buffers containing UTF-8 strings in a
-+** case-independent fashion, using the same definition of "case
-+** independence" that SQLite uses internally when comparing identifiers.
- */
--#ifdef __DJGPP__
--  { "fstat",        0,                 0  },
--#define osFstat(a,b,c)    0
--#else     
--  { "fstat",        (sqlite3_syscall_ptr)fstat,      0  },
--#define osFstat     ((int(*)(int,struct stat*))aSyscall[5].pCurrent)
--#endif
--
--  { "ftruncate",    (sqlite3_syscall_ptr)ftruncate,  0  },
--#define osFtruncate ((int(*)(int,off_t))aSyscall[6].pCurrent)
--
--  { "fcntl",        (sqlite3_syscall_ptr)fcntl,      0  },
--#define osFcntl     ((int(*)(int,int,...))aSyscall[7].pCurrent)
--
--  { "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
--  { "pread",        (sqlite3_syscall_ptr)pread,      0  },
--#else
--  { "pread",        (sqlite3_syscall_ptr)0,          0  },
--#endif
--#define osPread     ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[9].pCurrent)
--
--#if defined(USE_PREAD64)
--  { "pread64",      (sqlite3_syscall_ptr)pread64,    0  },
--#else
--  { "pread64",      (sqlite3_syscall_ptr)0,          0  },
--#endif
--#define osPread64   ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[10].pCurrent)
--
--  { "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
--  { "pwrite",       (sqlite3_syscall_ptr)pwrite,     0  },
--#else
--  { "pwrite",       (sqlite3_syscall_ptr)0,          0  },
--#endif
--#define osPwrite    ((ssize_t(*)(int,const void*,size_t,off_t))\
--                    aSyscall[12].pCurrent)
--
--#if defined(USE_PREAD64)
--  { "pwrite64",     (sqlite3_syscall_ptr)pwrite64,   0  },
--#else
--  { "pwrite64",     (sqlite3_syscall_ptr)0,          0  },
--#endif
--#define osPwrite64  ((ssize_t(*)(int,const void*,size_t,off_t))\
--                    aSyscall[13].pCurrent)
--
--  { "fchmod",       (sqlite3_syscall_ptr)fchmod,     0  },
--#define osFchmod    ((int(*)(int,mode_t))aSyscall[14].pCurrent)
--
--#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
--  { "fallocate",    (sqlite3_syscall_ptr)posix_fallocate,  0 },
--#else
--  { "fallocate",    (sqlite3_syscall_ptr)0,                0 },
--#endif
--#define osFallocate ((int(*)(int,off_t,off_t))aSyscall[15].pCurrent)
--
--  { "unlink",       (sqlite3_syscall_ptr)unlink,           0 },
--#define osUnlink    ((int(*)(const char*))aSyscall[16].pCurrent)
--
--  { "openDirectory",    (sqlite3_syscall_ptr)openDirectory,      0 },
--#define osOpenDirectory ((int(*)(const char*,int*))aSyscall[17].pCurrent)
-+SQLITE_API int sqlite3_stricmp(const char *zLeft, const char *zRight){
-+  register unsigned char *a, *b;
-+  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){
-+  register unsigned char *a, *b;
-+  a = (unsigned char *)zLeft;
-+  b = (unsigned char *)zRight;
-+  while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
-+  return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b];
-+}
- 
--  { "mkdir",        (sqlite3_syscall_ptr)mkdir,           0 },
--#define osMkdir     ((int(*)(const char*,mode_t))aSyscall[18].pCurrent)
-+/*
-+** The string z[] is an text representation of a real number.
-+** Convert this string to a double and write it into *pResult.
-+**
-+** The string z[] is length bytes in length (bytes, not characters) and
-+** uses the encoding enc.  The string is not necessarily zero-terminated.
-+**
-+** Return TRUE if the result is a valid real number (or integer) and FALSE
-+** if the string is empty or contains extraneous text.  Valid numbers
-+** are in one of these formats:
-+**
-+**    [+-]digits[E[+-]digits]
-+**    [+-]digits.[digits][E[+-]digits]
-+**    [+-].digits[E[+-]digits]
-+**
-+** Leading and trailing whitespace is ignored for the purpose of determining
-+** validity.
-+**
-+** If some prefix of the input string is a valid number, this routine
-+** returns FALSE but it still converts the prefix and writes the result
-+** into *pResult.
-+*/
-+SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
-+#ifndef SQLITE_OMIT_FLOATING_POINT
-+  int incr;
-+  const char *zEnd = z + length;
-+  /* sign * significand * (10 ^ (esign * exponent)) */
-+  int sign = 1;    /* sign of significand */
-+  i64 s = 0;       /* significand */
-+  int d = 0;       /* adjust exponent for shifting decimal point */
-+  int esign = 1;   /* sign of exponent */
-+  int e = 0;       /* exponent */
-+  int eValid = 1;  /* True exponent is either not used or is well-formed */
-+  double result;
-+  int nDigits = 0;
-+  int nonNum = 0;
- 
--  { "rmdir",        (sqlite3_syscall_ptr)rmdir,           0 },
--#define osRmdir     ((int(*)(const char*))aSyscall[19].pCurrent)
-+  assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
-+  *pResult = 0.0;   /* Default return value, in case of an error */
- 
--  { "fchown",       (sqlite3_syscall_ptr)posixFchown,     0 },
--#define osFchown    ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
-+  if( enc==SQLITE_UTF8 ){
-+    incr = 1;
-+  }else{
-+    int i;
-+    incr = 2;
-+    assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
-+    for(i=3-enc; i<length && z[i]==0; i+=2){}
-+    nonNum = i<length;
-+    zEnd = z+i+enc-3;
-+    z += (enc&1);
-+  }
- 
--  { "mmap",       (sqlite3_syscall_ptr)mmap,     0 },
--#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[21].pCurrent)
-+  /* skip leading spaces */
-+  while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
-+  if( z>=zEnd ) return 0;
- 
--  { "munmap",       (sqlite3_syscall_ptr)munmap,          0 },
--#define osMunmap ((void*(*)(void*,size_t))aSyscall[22].pCurrent)
-+  /* get sign of significand */
-+  if( *z=='-' ){
-+    sign = -1;
-+    z+=incr;
-+  }else if( *z=='+' ){
-+    z+=incr;
-+  }
- 
--#if HAVE_MREMAP
--  { "mremap",       (sqlite3_syscall_ptr)mremap,          0 },
--#else
--  { "mremap",       (sqlite3_syscall_ptr)0,               0 },
--#endif
--#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent)
-+  /* skip leading zeroes */
-+  while( z<zEnd && z[0]=='0' ) z+=incr, nDigits++;
- 
--}; /* End of the overrideable system calls */
-+  /* copy max significant digits to significand */
-+  while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
-+    s = s*10 + (*z - '0');
-+    z+=incr, nDigits++;
-+  }
- 
--/*
--** This is the xSetSystemCall() method of sqlite3_vfs for all of the
--** "unix" 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 unixSetSystemCall(
--  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;
-+  /* skip non-significant significand digits
-+  ** (increase exponent by d to shift decimal left) */
-+  while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++, d++;
-+  if( z>=zEnd ) goto do_atof_calc;
- 
--  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 decimal point is present */
-+  if( *z=='.' ){
-+    z+=incr;
-+    /* copy digits from after decimal to significand
-+    ** (decrease exponent by d to shift decimal right) */
-+    while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
-+      s = s*10 + (*z - '0');
-+      z+=incr, nDigits++, d--;
-     }
--  }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;
--      }
-+    /* skip non-significant digits */
-+    while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++;
-+  }
-+  if( z>=zEnd ) goto do_atof_calc;
-+
-+  /* if exponent is present */
-+  if( *z=='e' || *z=='E' ){
-+    z+=incr;
-+    eValid = 0;
-+    if( z>=zEnd ) goto do_atof_calc;
-+    /* get sign of exponent */
-+    if( *z=='-' ){
-+      esign = -1;
-+      z+=incr;
-+    }else if( *z=='+' ){
-+      z+=incr;
-+    }
-+    /* copy digits to exponent */
-+    while( z<zEnd && sqlite3Isdigit(*z) ){
-+      e = e<10000 ? (e*10 + (*z - '0')) : 10000;
-+      z+=incr;
-+      eValid = 1;
-     }
-   }
--  return rc;
--}
--
--/*
--** 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 unixGetSystemCall(
--  sqlite3_vfs *pNotUsed,
--  const char *zName
--){
--  unsigned int i;
- 
--  UNUSED_PARAMETER(pNotUsed);
--  for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
--    if( strcmp(zName, aSyscall[i].zName)==0 ) return aSyscall[i].pCurrent;
-+  /* skip trailing spaces */
-+  if( nDigits && eValid ){
-+    while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
-   }
--  return 0;
--}
- 
--/*
--** 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 *unixNextSystemCall(sqlite3_vfs *p, const char *zName){
--  int i = -1;
-+do_atof_calc:
-+  /* adjust exponent by d, and update sign */
-+  e = (e*esign) + d;
-+  if( e<0 ) {
-+    esign = -1;
-+    e *= -1;
-+  } else {
-+    esign = 1;
-+  }
- 
--  UNUSED_PARAMETER(p);
--  if( zName ){
--    for(i=0; i<ArraySize(aSyscall)-1; i++){
--      if( strcmp(zName, aSyscall[i].zName)==0 ) break;
-+  /* if 0 significand */
-+  if( !s ) {
-+    /* In the IEEE 754 standard, zero is signed.
-+    ** Add the sign if we've seen at least one digit */
-+    result = (sign<0 && nDigits) ? -(double)0 : (double)0;
-+  } else {
-+    /* attempt to reduce exponent */
-+    if( esign>0 ){
-+      while( s<(LARGEST_INT64/10) && e>0 ) e--,s*=10;
-+    }else{
-+      while( !(s%10) && e>0 ) e--,s/=10;
-     }
--  }
--  for(i++; i<ArraySize(aSyscall); i++){
--    if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
--  }
--  return 0;
--}
- 
--/*
--** Invoke open().  Do so multiple times, until it either succeeds or
--** fails for some reason other than EINTR.
--**
--** If the file creation mode "m" is 0 then set it to the default for
--** SQLite.  The default is SQLITE_DEFAULT_FILE_PERMISSIONS (normally
--** 0644) as modified by the system umask.  If m is not 0, then
--** make the file creation mode be exactly m ignoring the umask.
--**
--** The m parameter will be non-zero only when creating -wal, -journal,
--** and -shm files.  We want those files to have *exactly* the same
--** permissions as their original database, unadulterated by the umask.
--** In that way, if a database file is -rw-rw-rw or -rw-rw-r-, and a
--** transaction crashes and leaves behind hot journals, then any
--** process that is able to write to the database will also be able to
--** recover the hot journals.
--*/
--static int robust_open(const char *z, int f, mode_t m){
--  int fd;
--  mode_t m2 = m ? m : SQLITE_DEFAULT_FILE_PERMISSIONS;
--  do{
--#if defined(O_CLOEXEC)
--    fd = osOpen(z,f|O_CLOEXEC,m2);
--#else
--    fd = osOpen(z,f,m2);
--#endif
--  }while( fd<0 && errno==EINTR );
--  if( fd>=0 ){
--    if( m!=0 ){
--      struct stat statbuf;
--      if( osFstat(fd, &statbuf)==0 
--       && statbuf.st_size==0
--       && (statbuf.st_mode&0777)!=m 
--      ){
--        osFchmod(fd, m);
-+    /* adjust the sign of significand */
-+    s = sign<0 ? -s : s;
-+
-+    /* if exponent, scale significand as appropriate
-+    ** and store in result. */
-+    if( e ){
-+      LONGDOUBLE_TYPE scale = 1.0;
-+      /* attempt to handle extremely small/large numbers better */
-+      if( e>307 && e<342 ){
-+        while( e%308 ) { scale *= 1.0e+1; e -= 1; }
-+        if( esign<0 ){
-+          result = s / scale;
-+          result /= 1.0e+308;
-+        }else{
-+          result = s * scale;
-+          result *= 1.0e+308;
-+        }
-+      }else if( e>=342 ){
-+        if( esign<0 ){
-+          result = 0.0*s;
-+        }else{
-+          result = 1e308*1e308*s;  /* Infinity */
-+        }
-+      }else{
-+        /* 1.0e+22 is the largest power of 10 than can be 
-+        ** represented exactly. */
-+        while( e%22 ) { scale *= 1.0e+1; e -= 1; }
-+        while( e>0 ) { scale *= 1.0e+22; e -= 22; }
-+        if( esign<0 ){
-+          result = s / scale;
-+        }else{
-+          result = s * scale;
-+        }
-       }
-+    } else {
-+      result = (double)s;
-     }
--#if defined(FD_CLOEXEC) && (!defined(O_CLOEXEC) || O_CLOEXEC==0)
--    osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
--#endif
-   }
--  return fd;
-+
-+  /* store the result */
-+  *pResult = result;
-+
-+  /* return true if number and no extra non-whitespace chracters after */
-+  return z>=zEnd && nDigits>0 && eValid && nonNum==0;
-+#else
-+  return !sqlite3Atoi64(z, pResult, length, enc);
-+#endif /* SQLITE_OMIT_FLOATING_POINT */
- }
- 
- /*
--** Helper functions to obtain and relinquish the global mutex. The
--** global mutex is used to protect the unixInodeInfo and
--** vxworksFileId objects used by this file, all of which may be 
--** shared by multiple threads.
-+** Compare the 19-character string zNum against the text representation
-+** value 2^63:  9223372036854775808.  Return negative, zero, or positive
-+** if zNum is less than, equal to, or greater than the string.
-+** Note that zNum must contain exactly 19 characters.
- **
--** Function unixMutexHeld() is used to assert() that the global mutex 
--** is held when required. This function is only used as part of assert() 
--** statements. e.g.
-+** Unlike memcmp() this routine is guaranteed to return the difference
-+** in the values of the last digit if the only difference is in the
-+** last digit.  So, for example,
- **
--**   unixEnterMutex()
--**     assert( unixMutexHeld() );
--**   unixEnterLeave()
-+**      compare2pow63("9223372036854775800", 1)
-+**
-+** will return -8.
- */
--static void unixEnterMutex(void){
--  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
--}
--static void unixLeaveMutex(void){
--  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
--}
--#ifdef SQLITE_DEBUG
--static int unixMutexHeld(void) {
--  return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-+static int compare2pow63(const char *zNum, int incr){
-+  int c = 0;
-+  int i;
-+                    /* 012345678901234567 */
-+  const char *pow63 = "922337203685477580";
-+  for(i=0; c==0 && i<18; i++){
-+    c = (zNum[i*incr]-pow63[i])*10;
-+  }
-+  if( c==0 ){
-+    c = zNum[18*incr] - '8';
-+    testcase( c==(-1) );
-+    testcase( c==0 );
-+    testcase( c==(+1) );
-+  }
-+  return c;
- }
--#endif
- 
- 
--#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
- /*
--** Helper function for printing out trace information from debugging
--** binaries. This returns the string represetation of the supplied
--** integer lock-type.
-+** Convert zNum to a 64-bit signed integer.
-+**
-+** If the zNum value is representable as a 64-bit twos-complement 
-+** integer, then write that value into *pNum and return 0.
-+**
-+** If zNum is exactly 9223372036854665808, return 2.  This special
-+** case is broken out because while 9223372036854665808 cannot be a 
-+** signed 64-bit integer, its negative -9223372036854665808 can be.
-+**
-+** If zNum is too big for a 64-bit integer and is not
-+** 9223372036854665808  or if zNum contains any non-numeric text,
-+** then return 1.
-+**
-+** length is the number of bytes in the string (bytes, not characters).
-+** The string is not necessarily zero-terminated.  The encoding is
-+** given by enc.
- */
--static const char *azFileLock(int eFileLock){
--  switch( eFileLock ){
--    case NO_LOCK: return "NONE";
--    case SHARED_LOCK: return "SHARED";
--    case RESERVED_LOCK: return "RESERVED";
--    case PENDING_LOCK: return "PENDING";
--    case EXCLUSIVE_LOCK: return "EXCLUSIVE";
-+SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
-+  int incr;
-+  u64 u = 0;
-+  int neg = 0; /* assume positive */
-+  int i;
-+  int c = 0;
-+  int nonNum = 0;
-+  const char *zStart;
-+  const char *zEnd = zNum + length;
-+  assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
-+  if( enc==SQLITE_UTF8 ){
-+    incr = 1;
-+  }else{
-+    incr = 2;
-+    assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
-+    for(i=3-enc; i<length && zNum[i]==0; i+=2){}
-+    nonNum = i<length;
-+    zEnd = zNum+i+enc-3;
-+    zNum += (enc&1);
-+  }
-+  while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr;
-+  if( zNum<zEnd ){
-+    if( *zNum=='-' ){
-+      neg = 1;
-+      zNum+=incr;
-+    }else if( *zNum=='+' ){
-+      zNum+=incr;
-+    }
-+  }
-+  zStart = zNum;
-+  while( zNum<zEnd && zNum[0]=='0' ){ zNum+=incr; } /* Skip leading zeros. */
-+  for(i=0; &zNum[i]<zEnd && (c=zNum[i])>='0' && c<='9'; i+=incr){
-+    u = u*10 + c - '0';
-+  }
-+  if( u>LARGEST_INT64 ){
-+    *pNum = SMALLEST_INT64;
-+  }else if( neg ){
-+    *pNum = -(i64)u;
-+  }else{
-+    *pNum = (i64)u;
-+  }
-+  testcase( i==18 );
-+  testcase( i==19 );
-+  testcase( i==20 );
-+  if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum) || i>19*incr || nonNum ){
-+    /* zNum is empty or contains non-numeric text or is longer
-+    ** than 19 digits (thus guaranteeing that it is too large) */
-+    return 1;
-+  }else if( i<19*incr ){
-+    /* Less than 19 digits, so we know that it fits in 64 bits */
-+    assert( u<=LARGEST_INT64 );
-+    return 0;
-+  }else{
-+    /* zNum is a 19-digit numbers.  Compare it against 9223372036854775808. */
-+    c = compare2pow63(zNum, incr);
-+    if( c<0 ){
-+      /* zNum is less than 9223372036854775808 so it fits */
-+      assert( u<=LARGEST_INT64 );
-+      return 0;
-+    }else if( c>0 ){
-+      /* zNum is greater than 9223372036854775808 so it overflows */
-+      return 1;
-+    }else{
-+      /* zNum is exactly 9223372036854775808.  Fits if negative.  The
-+      ** special case 2 overflow if positive */
-+      assert( u-1==LARGEST_INT64 );
-+      assert( (*pNum)==SMALLEST_INT64 );
-+      return neg ? 0 : 2;
-+    }
-   }
--  return "ERROR";
- }
--#endif
- 
--#ifdef SQLITE_LOCK_TRACE
- /*
--** Print out information about all locking operations.
-+** If zNum represents an integer that will fit in 32-bits, then set
-+** *pValue to that integer and return true.  Otherwise return false.
- **
--** This routine is used for troubleshooting locks on multithreaded
--** platforms.  Enable by compiling with the -DSQLITE_LOCK_TRACE
--** command-line option on the compiler.  This code is normally
--** turned off.
-+** Any non-numeric characters that following zNum are ignored.
-+** This is different from sqlite3Atoi64() which requires the
-+** input number to be zero-terminated.
- */
--static int lockTrace(int fd, int op, struct flock *p){
--  char *zOpName, *zType;
--  int s;
--  int savedErrno;
--  if( op==F_GETLK ){
--    zOpName = "GETLK";
--  }else if( op==F_SETLK ){
--    zOpName = "SETLK";
--  }else{
--    s = osFcntl(fd, op, p);
--    sqlite3DebugPrintf("fcntl unknown %d %d %d\n", fd, op, s);
--    return s;
-+SQLITE_PRIVATE int sqlite3GetInt32(const char *zNum, int *pValue){
-+  sqlite_int64 v = 0;
-+  int i, c;
-+  int neg = 0;
-+  if( zNum[0]=='-' ){
-+    neg = 1;
-+    zNum++;
-+  }else if( zNum[0]=='+' ){
-+    zNum++;
-   }
--  if( p->l_type==F_RDLCK ){
--    zType = "RDLCK";
--  }else if( p->l_type==F_WRLCK ){
--    zType = "WRLCK";
--  }else if( p->l_type==F_UNLCK ){
--    zType = "UNLCK";
--  }else{
--    assert( 0 );
-+  while( zNum[0]=='0' ) zNum++;
-+  for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){
-+    v = v*10 + c;
-   }
--  assert( p->l_whence==SEEK_SET );
--  s = osFcntl(fd, op, p);
--  savedErrno = errno;
--  sqlite3DebugPrintf("fcntl %d %d %s %s %d %d %d %d\n",
--     threadid, fd, zOpName, zType, (int)p->l_start, (int)p->l_len,
--     (int)p->l_pid, s);
--  if( s==(-1) && op==F_SETLK && (p->l_type==F_RDLCK || p->l_type==F_WRLCK) ){
--    struct flock l2;
--    l2 = *p;
--    osFcntl(fd, F_GETLK, &l2);
--    if( l2.l_type==F_RDLCK ){
--      zType = "RDLCK";
--    }else if( l2.l_type==F_WRLCK ){
--      zType = "WRLCK";
--    }else if( l2.l_type==F_UNLCK ){
--      zType = "UNLCK";
--    }else{
--      assert( 0 );
--    }
--    sqlite3DebugPrintf("fcntl-failure-reason: %s %d %d %d\n",
--       zType, (int)l2.l_start, (int)l2.l_len, (int)l2.l_pid);
-+
-+  /* The longest decimal representation of a 32 bit integer is 10 digits:
-+  **
-+  **             1234567890
-+  **     2^31 -> 2147483648
-+  */
-+  testcase( i==10 );
-+  if( i>10 ){
-+    return 0;
-   }
--  errno = savedErrno;
--  return s;
-+  testcase( v-neg==2147483647 );
-+  if( v-neg>2147483647 ){
-+    return 0;
-+  }
-+  if( neg ){
-+    v = -v;
-+  }
-+  *pValue = (int)v;
-+  return 1;
- }
--#undef osFcntl
--#define osFcntl lockTrace
--#endif /* SQLITE_LOCK_TRACE */
- 
- /*
--** Retry ftruncate() calls that fail due to EINTR
-+** Return a 32-bit integer value extracted from a string.  If the
-+** string is not an integer, just return 0.
- */
--static int robust_ftruncate(int h, sqlite3_int64 sz){
--  int rc;
--  do{ rc = osFtruncate(h,sz); }while( rc<0 && errno==EINTR );
--  return rc;
-+SQLITE_PRIVATE int sqlite3Atoi(const char *z){
-+  int x = 0;
-+  if( z ) sqlite3GetInt32(z, &x);
-+  return x;
- }
- 
- /*
--** This routine translates a standard POSIX errno code into something
--** useful to the clients of the sqlite3 functions.  Specifically, it is
--** intended to translate a variety of "try again" errors into SQLITE_BUSY
--** and a variety of "please close the file descriptor NOW" errors into 
--** SQLITE_IOERR
--** 
--** Errors during initialization of locks, or file system support for locks,
--** should handle ENOLCK, ENOTSUP, EOPNOTSUPP separately.
-+** The variable-length integer encoding is as follows:
-+**
-+** KEY:
-+**         A = 0xxxxxxx    7 bits of data and one flag bit
-+**         B = 1xxxxxxx    7 bits of data and one flag bit
-+**         C = xxxxxxxx    8 bits of data
-+**
-+**  7 bits - A
-+** 14 bits - BA
-+** 21 bits - BBA
-+** 28 bits - BBBA
-+** 35 bits - BBBBA
-+** 42 bits - BBBBBA
-+** 49 bits - BBBBBBA
-+** 56 bits - BBBBBBBA
-+** 64 bits - BBBBBBBBC
- */
--static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) {
--  switch (posixError) {
--#if 0
--  /* At one point this code was not commented out. In theory, this branch
--  ** should never be hit, as this function should only be called after
--  ** a locking-related function (i.e. fcntl()) has returned non-zero with
--  ** the value of errno as the first argument. Since a system call has failed,
--  ** errno should be non-zero.
--  **
--  ** Despite this, if errno really is zero, we still don't want to return
--  ** SQLITE_OK. The system call failed, and *some* SQLite error should be
--  ** propagated back to the caller. Commenting this branch out means errno==0
--  ** will be handled by the "default:" case below.
--  */
--  case 0: 
--    return SQLITE_OK;
--#endif
- 
--  case EAGAIN:
--  case ETIMEDOUT:
--  case EBUSY:
--  case EINTR:
--  case ENOLCK:  
--    /* random NFS retry error, unless during file system support 
--     * introspection, in which it actually means what it says */
--    return SQLITE_BUSY;
--    
--  case EACCES: 
--    /* EACCES is like EAGAIN during locking operations, but not any other time*/
--    if( (sqliteIOErr == SQLITE_IOERR_LOCK) || 
--        (sqliteIOErr == SQLITE_IOERR_UNLOCK) || 
--        (sqliteIOErr == SQLITE_IOERR_RDLOCK) ||
--        (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ){
--      return SQLITE_BUSY;
-+/*
-+** Write a 64-bit variable-length integer to memory starting at p[0].
-+** The length of data write will be between 1 and 9 bytes.  The number
-+** of bytes written is returned.
-+**
-+** A variable-length integer consists of the lower 7 bits of each byte
-+** for all bytes that have the 8th bit set and one byte with the 8th
-+** 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){
-+  int i, j, n;
-+  u8 buf[10];
-+  if( v & (((u64)0xff000000)<<32) ){
-+    p[8] = (u8)v;
-+    v >>= 8;
-+    for(i=7; i>=0; i--){
-+      p[i] = (u8)((v & 0x7f) | 0x80);
-+      v >>= 7;
-     }
--    /* else fall through */
--  case EPERM: 
--    return SQLITE_PERM;
--    
--  /* EDEADLK is only possible if a call to fcntl(F_SETLKW) is made. And
--  ** this module never makes such a call. And the code in SQLite itself 
--  ** asserts that SQLITE_IOERR_BLOCKED is never returned. For these reasons
--  ** this case is also commented out. If the system does set errno to EDEADLK,
--  ** the default SQLITE_IOERR_XXX code will be returned. */
--#if 0
--  case EDEADLK:
--    return SQLITE_IOERR_BLOCKED;
--#endif
--    
--#if EOPNOTSUPP!=ENOTSUP
--  case EOPNOTSUPP: 
--    /* something went terribly awry, unless during file system support 
--     * introspection, in which it actually means what it says */
--#endif
--#ifdef ENOTSUP
--  case ENOTSUP: 
--    /* invalid fd, unless during file system support introspection, in which 
--     * it actually means what it says */
--#endif
--  case EIO:
--  case EBADF:
--  case EINVAL:
--  case ENOTCONN:
--  case ENODEV:
--  case ENXIO:
--  case ENOENT:
--#ifdef ESTALE                     /* ESTALE is not defined on Interix systems */
--  case ESTALE:
--#endif
--  case ENOSYS:
--    /* these should force the client to close the file and reconnect */
--    
--  default: 
--    return sqliteIOErr;
-+    return 9;
-+  }    
-+  n = 0;
-+  do{
-+    buf[n++] = (u8)((v & 0x7f) | 0x80);
-+    v >>= 7;
-+  }while( v!=0 );
-+  buf[0] &= 0x7f;
-+  assert( n<=9 );
-+  for(i=0, j=n-1; j>=0; j--, i++){
-+    p[i] = buf[j];
-   }
-+  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;
-+    return 1;
-+  }
-+#endif
-+  if( (v & ~0x3fff)==0 ){
-+    p[0] = (u8)((v>>7) | 0x80);
-+    p[1] = (u8)(v & 0x7f);
-+    return 2;
-+  }
-+  return sqlite3PutVarint(p, v);
-+}
- 
--/******************************************************************************
--****************** Begin Unique File ID Utility Used By VxWorks ***************
--**
--** On most versions of unix, we can get a unique ID for a file by concatenating
--** the device number and the inode number.  But this does not work on VxWorks.
--** On VxWorks, a unique file id must be based on the canonical filename.
-+/*
-+** Bitmasks used by sqlite3GetVarint().  These precomputed constants
-+** are defined here rather than simply putting the constant expressions
-+** inline in order to work around bugs in the RVT compiler.
- **
--** A pointer to an instance of the following structure can be used as a
--** unique file ID in VxWorks.  Each instance of this structure contains
--** a copy of the canonical filename.  There is also a reference count.  
--** The structure is reclaimed when the number of pointers to it drops to
--** zero.
-+** SLOT_2_0     A mask for  (0x7f<<14) | 0x7f
- **
--** There are never very many files open at one time and lookups are not
--** a performance-critical path, so it is sufficient to put these
--** structures on a linked list.
-+** SLOT_4_2_0   A mask for  (0x7f<<28) | SLOT_2_0
- */
--struct vxworksFileId {
--  struct vxworksFileId *pNext;  /* Next in a list of them all */
--  int nRef;                     /* Number of references to this one */
--  int nName;                    /* Length of the zCanonicalName[] string */
--  char *zCanonicalName;         /* Canonical filename */
--};
-+#define SLOT_2_0     0x001fc07f
-+#define SLOT_4_2_0   0xf01fc07f
- 
--#if OS_VXWORKS
--/* 
--** All unique filenames are held on a linked list headed by this
--** variable:
--*/
--static struct vxworksFileId *vxworksFileList = 0;
- 
- /*
--** Simplify a filename into its canonical form
--** by making the following changes:
--**
--**  * removing any trailing and duplicate /
--**  * convert /./ into just /
--**  * convert /A/../ where A is any simple name into just /
--**
--** Changes are made in-place.  Return the new name length.
--**
--** The original filename is in z[0..n-1].  Return the number of
--** characters in the simplified name.
-+** Read a 64-bit variable-length integer from memory starting at p[0].
-+** Return the number of bytes read.  The value is stored in *v.
- */
--static int vxworksSimplifyName(char *z, int n){
--  int i, j;
--  while( n>1 && z[n-1]=='/' ){ n--; }
--  for(i=j=0; i<n; i++){
--    if( z[i]=='/' ){
--      if( z[i+1]=='/' ) continue;
--      if( z[i+1]=='.' && i+2<n && z[i+2]=='/' ){
--        i += 1;
--        continue;
--      }
--      if( z[i+1]=='.' && i+3<n && z[i+2]=='.' && z[i+3]=='/' ){
--        while( j>0 && z[j-1]!='/' ){ j--; }
--        if( j>0 ){ j--; }
--        i += 2;
--        continue;
--      }
--    }
--    z[j++] = z[i];
-+SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){
-+  u32 a,b,s;
-+
-+  a = *p;
-+  /* a: p0 (unmasked) */
-+  if (!(a&0x80))
-+  {
-+    *v = a;
-+    return 1;
-   }
--  z[j] = 0;
--  return j;
-+
-+  p++;
-+  b = *p;
-+  /* b: p1 (unmasked) */
-+  if (!(b&0x80))
-+  {
-+    a &= 0x7f;
-+    a = a<<7;
-+    a |= b;
-+    *v = a;
-+    return 2;
-+  }
-+
-+  /* Verify that constants are precomputed correctly */
-+  assert( SLOT_2_0 == ((0x7f<<14) | (0x7f)) );
-+  assert( SLOT_4_2_0 == ((0xfU<<28) | (0x7f<<14) | (0x7f)) );
-+
-+  p++;
-+  a = a<<14;
-+  a |= *p;
-+  /* a: p0<<14 | p2 (unmasked) */
-+  if (!(a&0x80))
-+  {
-+    a &= SLOT_2_0;
-+    b &= 0x7f;
-+    b = b<<7;
-+    a |= b;
-+    *v = a;
-+    return 3;
-+  }
-+
-+  /* CSE1 from below */
-+  a &= SLOT_2_0;
-+  p++;
-+  b = b<<14;
-+  b |= *p;
-+  /* b: p1<<14 | p3 (unmasked) */
-+  if (!(b&0x80))
-+  {
-+    b &= SLOT_2_0;
-+    /* moved CSE1 up */
-+    /* a &= (0x7f<<14)|(0x7f); */
-+    a = a<<7;
-+    a |= b;
-+    *v = a;
-+    return 4;
-+  }
-+
-+  /* a: p0<<14 | p2 (masked) */
-+  /* b: p1<<14 | p3 (unmasked) */
-+  /* 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
-+  /* moved CSE1 up */
-+  /* a &= (0x7f<<14)|(0x7f); */
-+  b &= SLOT_2_0;
-+  s = a;
-+  /* s: p0<<14 | p2 (masked) */
-+
-+  p++;
-+  a = a<<14;
-+  a |= *p;
-+  /* a: p0<<28 | p2<<14 | p4 (unmasked) */
-+  if (!(a&0x80))
-+  {
-+    /* we can skip these cause they were (effectively) done above in calc'ing s */
-+    /* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */
-+    /* b &= (0x7f<<14)|(0x7f); */
-+    b = b<<7;
-+    a |= b;
-+    s = s>>18;
-+    *v = ((u64)s)<<32 | a;
-+    return 5;
-+  }
-+
-+  /* 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
-+  s = s<<7;
-+  s |= b;
-+  /* s: p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
-+
-+  p++;
-+  b = b<<14;
-+  b |= *p;
-+  /* b: p1<<28 | p3<<14 | p5 (unmasked) */
-+  if (!(b&0x80))
-+  {
-+    /* we can skip this cause it was (effectively) done above in calc'ing s */
-+    /* b &= (0x7f<<28)|(0x7f<<14)|(0x7f); */
-+    a &= SLOT_2_0;
-+    a = a<<7;
-+    a |= b;
-+    s = s>>18;
-+    *v = ((u64)s)<<32 | a;
-+    return 6;
-+  }
-+
-+  p++;
-+  a = a<<14;
-+  a |= *p;
-+  /* a: p2<<28 | p4<<14 | p6 (unmasked) */
-+  if (!(a&0x80))
-+  {
-+    a &= SLOT_4_2_0;
-+    b &= SLOT_2_0;
-+    b = b<<7;
-+    a |= b;
-+    s = s>>11;
-+    *v = ((u64)s)<<32 | a;
-+    return 7;
-+  }
-+
-+  /* CSE2 from below */
-+  a &= SLOT_2_0;
-+  p++;
-+  b = b<<14;
-+  b |= *p;
-+  /* b: p3<<28 | p5<<14 | p7 (unmasked) */
-+  if (!(b&0x80))
-+  {
-+    b &= SLOT_4_2_0;
-+    /* moved CSE2 up */
-+    /* a &= (0x7f<<14)|(0x7f); */
-+    a = a<<7;
-+    a |= b;
-+    s = s>>4;
-+    *v = ((u64)s)<<32 | a;
-+    return 8;
-+  }
-+
-+  p++;
-+  a = a<<15;
-+  a |= *p;
-+  /* a: p4<<29 | p6<<15 | p8 (unmasked) */
-+
-+  /* moved CSE2 up */
-+  /* a &= (0x7f<<29)|(0x7f<<15)|(0xff); */
-+  b &= SLOT_2_0;
-+  b = b<<8;
-+  a |= b;
-+
-+  s = s<<4;
-+  b = p[-4];
-+  b &= 0x7f;
-+  b = b>>3;
-+  s |= b;
-+
-+  *v = ((u64)s)<<32 | a;
-+
-+  return 9;
- }
- 
- /*
--** Find a unique file ID for the given absolute pathname.  Return
--** a pointer to the vxworksFileId object.  This pointer is the unique
--** file ID.
-+** Read a 32-bit variable-length integer from memory starting at p[0].
-+** Return the number of bytes read.  The value is stored in *v.
- **
--** The nRef field of the vxworksFileId object is incremented before
--** the object is returned.  A new vxworksFileId object is created
--** and added to the global list if necessary.
-+** If the varint stored in p[0] is larger than can fit in a 32-bit unsigned
-+** integer, then set *v to 0xffffffff.
- **
--** If a memory allocation error occurs, return NULL.
-+** A MACRO version, getVarint32, 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.
- */
--static struct vxworksFileId *vxworksFindFileId(const char *zAbsoluteName){
--  struct vxworksFileId *pNew;         /* search key and new file ID */
--  struct vxworksFileId *pCandidate;   /* For looping over existing file IDs */
--  int n;                              /* Length of zAbsoluteName string */
-+SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){
-+  u32 a,b;
- 
--  assert( zAbsoluteName[0]=='/' );
--  n = (int)strlen(zAbsoluteName);
--  pNew = sqlite3_malloc( sizeof(*pNew) + (n+1) );
--  if( pNew==0 ) return 0;
--  pNew->zCanonicalName = (char*)&pNew[1];
--  memcpy(pNew->zCanonicalName, zAbsoluteName, n+1);
--  n = vxworksSimplifyName(pNew->zCanonicalName, n);
-+  /* The 1-byte case.  Overwhelmingly the most common.  Handled inline
-+  ** by the getVarin32() macro */
-+  a = *p;
-+  /* a: p0 (unmasked) */
-+#ifndef getVarint32
-+  if (!(a&0x80))
-+  {
-+    /* Values between 0 and 127 */
-+    *v = a;
-+    return 1;
-+  }
-+#endif
- 
--  /* Search for an existing entry that matching the canonical name.
--  ** If found, increment the reference count and return a pointer to
--  ** the existing file ID.
-+  /* The 2-byte case */
-+  p++;
-+  b = *p;
-+  /* b: p1 (unmasked) */
-+  if (!(b&0x80))
-+  {
-+    /* Values between 128 and 16383 */
-+    a &= 0x7f;
-+    a = a<<7;
-+    *v = a | b;
-+    return 2;
-+  }
-+
-+  /* The 3-byte case */
-+  p++;
-+  a = a<<14;
-+  a |= *p;
-+  /* a: p0<<14 | p2 (unmasked) */
-+  if (!(a&0x80))
-+  {
-+    /* Values between 16384 and 2097151 */
-+    a &= (0x7f<<14)|(0x7f);
-+    b &= 0x7f;
-+    b = b<<7;
-+    *v = a | b;
-+    return 3;
-+  }
-+
-+  /* A 32-bit varint is used to store size information in btrees.
-+  ** Objects are rarely larger than 2MiB limit of a 3-byte varint.
-+  ** A 3-byte varint is sufficient, for example, to record the size
-+  ** of a 1048569-byte BLOB or string.
-+  **
-+  ** We only unroll the first 1-, 2-, and 3- byte cases.  The very
-+  ** rare larger cases can be handled by the slower 64-bit varint
-+  ** routine.
-   */
--  unixEnterMutex();
--  for(pCandidate=vxworksFileList; pCandidate; pCandidate=pCandidate->pNext){
--    if( pCandidate->nName==n 
--     && memcmp(pCandidate->zCanonicalName, pNew->zCanonicalName, n)==0
--    ){
--       sqlite3_free(pNew);
--       pCandidate->nRef++;
--       unixLeaveMutex();
--       return pCandidate;
-+#if 1
-+  {
-+    u64 v64;
-+    u8 n;
-+
-+    p -= 2;
-+    n = sqlite3GetVarint(p, &v64);
-+    assert( n>3 && n<=9 );
-+    if( (v64 & SQLITE_MAX_U32)!=v64 ){
-+      *v = 0xffffffff;
-+    }else{
-+      *v = (u32)v64;
-     }
-+    return n;
-   }
- 
--  /* No match was found.  We will make a new file ID */
--  pNew->nRef = 1;
--  pNew->nName = n;
--  pNew->pNext = vxworksFileList;
--  vxworksFileList = pNew;
--  unixLeaveMutex();
--  return pNew;
--}
-+#else
-+  /* For following code (kept for historical record only) shows an
-+  ** unrolling for the 3- and 4-byte varint cases.  This code is
-+  ** slightly faster, but it is also larger and much harder to test.
-+  */
-+  p++;
-+  b = b<<14;
-+  b |= *p;
-+  /* b: p1<<14 | p3 (unmasked) */
-+  if (!(b&0x80))
-+  {
-+    /* Values between 2097152 and 268435455 */
-+    b &= (0x7f<<14)|(0x7f);
-+    a &= (0x7f<<14)|(0x7f);
-+    a = a<<7;
-+    *v = a | b;
-+    return 4;
-+  }
- 
--/*
--** Decrement the reference count on a vxworksFileId object.  Free
--** the object when the reference count reaches zero.
--*/
--static void vxworksReleaseFileId(struct vxworksFileId *pId){
--  unixEnterMutex();
--  assert( pId->nRef>0 );
--  pId->nRef--;
--  if( pId->nRef==0 ){
--    struct vxworksFileId **pp;
--    for(pp=&vxworksFileList; *pp && *pp!=pId; pp = &((*pp)->pNext)){}
--    assert( *pp==pId );
--    *pp = pId->pNext;
--    sqlite3_free(pId);
-+  p++;
-+  a = a<<14;
-+  a |= *p;
-+  /* a: p0<<28 | p2<<14 | p4 (unmasked) */
-+  if (!(a&0x80))
-+  {
-+    /* Values  between 268435456 and 34359738367 */
-+    a &= SLOT_4_2_0;
-+    b &= SLOT_4_2_0;
-+    b = b<<7;
-+    *v = a | b;
-+    return 5;
-   }
--  unixLeaveMutex();
--}
--#endif /* OS_VXWORKS */
--/*************** End of Unique File ID Utility Used By VxWorks ****************
--******************************************************************************/
- 
-+  /* We can only reach this point when reading a corrupt database
-+  ** file.  In that case we are not in any hurry.  Use the (relatively
-+  ** slow) general-purpose sqlite3GetVarint() routine to extract the
-+  ** value. */
-+  {
-+    u64 v64;
-+    u8 n;
- 
--/******************************************************************************
--*************************** Posix Advisory Locking ****************************
--**
--** POSIX advisory locks are broken by design.  ANSI STD 1003.1 (1996)
--** section 6.5.2.2 lines 483 through 490 specify that when a process
--** sets or clears a lock, that operation overrides any prior locks set
--** by the same process.  It does not explicitly say so, but this implies
--** that it overrides locks set by the same process using a different
--** file descriptor.  Consider this test case:
--**
--**       int fd1 = open("./file1", O_RDWR|O_CREAT, 0644);
--**       int fd2 = open("./file2", O_RDWR|O_CREAT, 0644);
--**
--** Suppose ./file1 and ./file2 are really the same file (because
--** one is a hard or symbolic link to the other) then if you set
--** an exclusive lock on fd1, then try to get an exclusive lock
--** on fd2, it works.  I would have expected the second lock to
--** fail since there was already a lock on the file due to fd1.
--** But not so.  Since both locks came from the same process, the
--** second overrides the first, even though they were on different
--** file descriptors opened on different file names.
--**
--** This means that we cannot use POSIX locks to synchronize file access
--** among competing threads of the same process.  POSIX locks will work fine
--** to synchronize access for threads in separate processes, but not
--** threads within the same process.
--**
--** To work around the problem, SQLite has to manage file locks internally
--** on its own.  Whenever a new database is opened, we have to find the
--** specific inode of the database file (the inode is determined by the
--** st_dev and st_ino fields of the stat structure that fstat() fills in)
--** and check for locks already existing on that inode.  When locks are
--** created or removed, we have to look at our own internal record of the
--** locks to see if another thread has previously set a lock on that same
--** inode.
--**
--** (Aside: The use of inode numbers as unique IDs does not work on VxWorks.
--** For VxWorks, we have to use the alternative unique ID system based on
--** canonical filename and implemented in the previous division.)
--**
--** The sqlite3_file structure for POSIX is no longer just an integer file
--** descriptor.  It is now a structure that holds the integer file
--** descriptor and a pointer to a structure that describes the internal
--** locks on the corresponding inode.  There is one locking structure
--** per inode, so if the same inode is opened twice, both unixFile structures
--** point to the same locking structure.  The locking structure keeps
--** a reference count (so we will know when to delete it) and a "cnt"
--** field that tells us its internal lock status.  cnt==0 means the
--** file is unlocked.  cnt==-1 means the file has an exclusive lock.
--** cnt>0 means there are cnt shared locks on the file.
--**
--** Any attempt to lock or unlock a file first checks the locking
--** structure.  The fcntl() system call is only invoked to set a 
--** POSIX lock if the internal lock structure transitions between
--** a locked and an unlocked state.
--**
--** But wait:  there are yet more problems with POSIX advisory locks.
--**
--** If you close a file descriptor that points to a file that has locks,
--** all locks on that file that are owned by the current process are
--** released.  To work around this problem, each unixInodeInfo object
--** maintains a count of the number of pending locks on tha inode.
--** When an attempt is made to close an unixFile, if there are
--** other unixFile open on the same inode that are holding locks, the call
--** to close() the file descriptor is deferred until all of the locks clear.
--** The unixInodeInfo structure keeps a list of file descriptors that need to
--** be closed and that list is walked (and cleared) when the last lock
--** clears.
--**
--** Yet another problem:  LinuxThreads do not play well with posix locks.
--**
--** Many older versions of linux use the LinuxThreads library which is
--** not posix compliant.  Under LinuxThreads, a lock created by thread
--** A cannot be modified or overridden by a different thread B.
--** Only thread A can modify the lock.  Locking behavior is correct
--** if the appliation uses the newer Native Posix Thread Library (NPTL)
--** on linux - with NPTL a lock created by thread A can override locks
--** in thread B.  But there is no way to know at compile-time which
--** threading library is being used.  So there is no way to know at
--** compile-time whether or not thread A can override locks on thread B.
--** One has to do a run-time check to discover the behavior of the
--** current process.
--**
--** SQLite used to support LinuxThreads.  But support for LinuxThreads
--** was dropped beginning with version 3.7.0.  SQLite will still work with
--** LinuxThreads provided that (1) there is no more than one connection 
--** per database file in the same process and (2) database connections
--** do not move across threads.
-+    p -= 4;
-+    n = sqlite3GetVarint(p, &v64);
-+    assert( n>5 && n<=9 );
-+    *v = (u32)v64;
-+    return n;
-+  }
-+#endif
-+}
-+
-+/*
-+** Return the number of bytes that will be needed to store the given
-+** 64-bit integer.
- */
-+SQLITE_PRIVATE int sqlite3VarintLen(u64 v){
-+  int i = 0;
-+  do{
-+    i++;
-+    v >>= 7;
-+  }while( v!=0 && ALWAYS(i<9) );
-+  return i;
-+}
-+
- 
- /*
--** An instance of the following structure serves as the key used
--** to locate a particular unixInodeInfo object.
-+** Read or write a four-byte big-endian integer value.
- */
--struct unixFileId {
--  dev_t dev;                  /* Device number */
--#if OS_VXWORKS
--  struct vxworksFileId *pId;  /* Unique file ID for vxworks. */
--#else
--  ino_t ino;                  /* Inode number */
--#endif
--};
-+SQLITE_PRIVATE u32 sqlite3Get4byte(const u8 *p){
-+  return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
-+}
-+SQLITE_PRIVATE void sqlite3Put4byte(unsigned char *p, u32 v){
-+  p[0] = (u8)(v>>24);
-+  p[1] = (u8)(v>>16);
-+  p[2] = (u8)(v>>8);
-+  p[3] = (u8)v;
-+}
-+
-+
- 
- /*
--** An instance of the following structure is allocated for each open
--** inode.  Or, on LinuxThreads, there is one of these structures for
--** each inode opened by each thread.
--**
--** A single inode can have multiple file descriptors, so each unixFile
--** structure contains a pointer to an instance of this object and this
--** object keeps a count of the number of unixFile pointing to it.
-+** Translate a single byte of Hex into an integer.
-+** This routine only works if h really is a valid hexadecimal
-+** character:  0..9a..fA..F
- */
--struct unixInodeInfo {
--  struct unixFileId fileId;       /* The lookup key */
--  int nShared;                    /* Number of SHARED locks held */
--  unsigned char eFileLock;        /* One of SHARED_LOCK, RESERVED_LOCK etc. */
--  unsigned char bProcessLock;     /* An exclusive process lock is held */
--  int nRef;                       /* Number of pointers to this structure */
--  unixShmNode *pShmNode;          /* Shared memory associated with this inode */
--  int nLock;                      /* Number of outstanding file locks */
--  UnixUnusedFd *pUnused;          /* Unused file descriptors to close */
--  unixInodeInfo *pNext;           /* List of all unixInodeInfo objects */
--  unixInodeInfo *pPrev;           /*    .... doubly linked */
--#if SQLITE_ENABLE_LOCKING_STYLE
--  unsigned long long sharedByte;  /* for AFP simulated shared lock */
-+SQLITE_PRIVATE u8 sqlite3HexToInt(int h){
-+  assert( (h>='0' && h<='9') ||  (h>='a' && h<='f') ||  (h>='A' && h<='F') );
-+#ifdef SQLITE_ASCII
-+  h += 9*(1&(h>>6));
- #endif
--#if OS_VXWORKS
--  sem_t *pSem;                    /* Named POSIX semaphore */
--  char aSemName[MAX_PATHNAME+2];  /* Name of that semaphore */
-+#ifdef SQLITE_EBCDIC
-+  h += 9*(1&~(h>>4));
- #endif
--};
-+  return (u8)(h & 0xf);
-+}
- 
-+#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC)
- /*
--** A lists of all unixInodeInfo objects.
-+** Convert a BLOB literal of the form "x'hhhhhh'" into its binary
-+** value.  Return a pointer to its binary value.  Space to hold the
-+** binary value has been obtained from malloc and must be freed by
-+** the calling routine.
- */
--static unixInodeInfo *inodeList = 0;
-+SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){
-+  char *zBlob;
-+  int i;
-+
-+  zBlob = (char *)sqlite3DbMallocRaw(db, n/2 + 1);
-+  n--;
-+  if( zBlob ){
-+    for(i=0; i<n; i+=2){
-+      zBlob[i/2] = (sqlite3HexToInt(z[i])<<4) | sqlite3HexToInt(z[i+1]);
-+    }
-+    zBlob[i/2] = 0;
-+  }
-+  return zBlob;
-+}
-+#endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC */
- 
- /*
--**
--** This function - unixLogError_x(), is only ever called via the macro
--** unixLogError().
--**
--** It is invoked after an error occurs in an OS function and errno has been
--** set. It logs a message using sqlite3_log() containing the current value of
--** errno and, if possible, the human-readable equivalent from strerror() or
--** strerror_r().
--**
--** 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 (e.g. "unlink", "open") and the associated file-system path,
--** if any.
-+** Log an error that is an API call on a connection pointer that should
-+** not have been used.  The "type" of connection pointer is given as the
-+** argument.  The zType is a word like "NULL" or "closed" or "invalid".
- */
--#define unixLogError(a,b,c)     unixLogErrorAtLine(a,b,c,__LINE__)
--static int unixLogErrorAtLine(
--  int errcode,                    /* SQLite error code */
--  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 *zErr;                     /* Message from strerror() or equivalent */
--  int iErrno = errno;             /* Saved syscall error number */
--
--  /* If this is not a threadsafe build (SQLITE_THREADSAFE==0), then use
--  ** the strerror() function to obtain the human-readable error message
--  ** equivalent to errno. Otherwise, use strerror_r().
--  */ 
--#if SQLITE_THREADSAFE && defined(HAVE_STRERROR_R)
--  char aErr[80];
--  memset(aErr, 0, sizeof(aErr));
--  zErr = aErr;
--
--  /* If STRERROR_R_CHAR_P (set by autoconf scripts) or __USE_GNU is defined,
--  ** assume that the system provides the GNU version of strerror_r() that
--  ** returns a pointer to a buffer containing the error message. That pointer 
--  ** may point to aErr[], or it may point to some static storage somewhere. 
--  ** Otherwise, assume that the system provides the POSIX version of 
--  ** strerror_r(), which always writes an error message into aErr[].
--  **
--  ** If the code incorrectly assumes that it is the POSIX version that is
--  ** available, the error message will often be an empty string. Not a
--  ** huge problem. Incorrectly concluding that the GNU version is available 
--  ** could lead to a segfault though.
--  */
--#if defined(STRERROR_R_CHAR_P) || defined(__USE_GNU)
--  zErr = 
--# endif
--  strerror_r(iErrno, aErr, sizeof(aErr)-1);
--
--#elif SQLITE_THREADSAFE
--  /* This is a threadsafe build, but strerror_r() is not available. */
--  zErr = "";
--#else
--  /* Non-threadsafe build, use strerror(). */
--  zErr = strerror(iErrno);
--#endif
--
--  if( zPath==0 ) zPath = "";
--  sqlite3_log(errcode,
--      "os_unix.c:%d: (%d) %s(%s) - %s",
--      iLine, iErrno, zFunc, zPath, zErr
-+static void logBadConnection(const char *zType){
-+  sqlite3_log(SQLITE_MISUSE, 
-+     "API call with %s database connection pointer",
-+     zType
-   );
--
--  return errcode;
- }
- 
- /*
--** Close a file descriptor.
--**
--** We assume that close() almost always works, since it is only in a
--** very sick application or on a very sick platform that it might fail.
--** If it does fail, simply leak the file descriptor, but do log the
--** error.
-+** Check to make sure we have a valid db pointer.  This test is not
-+** foolproof but it does provide some measure of protection against
-+** misuse of the interface such as passing in db pointers that are
-+** NULL or which have been previously closed.  If this routine returns
-+** 1 it means that the db pointer is valid and 0 if it should not be
-+** dereferenced for any reason.  The calling function should invoke
-+** SQLITE_MISUSE immediately.
- **
--** Note that it is not safe to retry close() after EINTR since the
--** file descriptor might have already been reused by another thread.
--** So we don't even try to recover from an EINTR.  Just log the error
--** and move on.
-+** sqlite3SafetyCheckOk() requires that the db pointer be valid for
-+** use.  sqlite3SafetyCheckSickOrOk() allows a db pointer that failed to
-+** open properly and is not fit for general use but which can be
-+** used as an argument to sqlite3_errmsg() or sqlite3_close().
- */
--static void robust_close(unixFile *pFile, int h, int lineno){
--  if( osClose(h) ){
--    unixLogErrorAtLine(SQLITE_IOERR_CLOSE, "close",
--                       pFile ? pFile->zPath : 0, lineno);
-+SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3 *db){
-+  u32 magic;
-+  if( db==0 ){
-+    logBadConnection("NULL");
-+    return 0;
-+  }
-+  magic = db->magic;
-+  if( magic!=SQLITE_MAGIC_OPEN ){
-+    if( sqlite3SafetyCheckSickOrOk(db) ){
-+      testcase( sqlite3GlobalConfig.xLog!=0 );
-+      logBadConnection("unopened");
-+    }
-+    return 0;
-+  }else{
-+    return 1;
-+  }
-+}
-+SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3 *db){
-+  u32 magic;
-+  magic = db->magic;
-+  if( magic!=SQLITE_MAGIC_SICK &&
-+      magic!=SQLITE_MAGIC_OPEN &&
-+      magic!=SQLITE_MAGIC_BUSY ){
-+    testcase( sqlite3GlobalConfig.xLog!=0 );
-+    logBadConnection("invalid");
-+    return 0;
-+  }else{
-+    return 1;
-   }
- }
- 
- /*
--** Close all file descriptors accumuated in the unixInodeInfo->pUnused list.
--*/ 
--static void closePendingFds(unixFile *pFile){
--  unixInodeInfo *pInode = pFile->pInode;
--  UnixUnusedFd *p;
--  UnixUnusedFd *pNext;
--  for(p=pInode->pUnused; p; p=pNext){
--    pNext = p->pNext;
--    robust_close(pFile, p->fd, __LINE__);
--    sqlite3_free(p);
-+** Attempt to add, substract, or multiply the 64-bit signed value iB against
-+** the other 64-bit signed integer at *pA and store the result in *pA.
-+** Return 0 on success.  Or if the operation would have resulted in an
-+** overflow, leave *pA unchanged and return 1.
-+*/
-+SQLITE_PRIVATE int sqlite3AddInt64(i64 *pA, i64 iB){
-+  i64 iA = *pA;
-+  testcase( iA==0 ); testcase( iA==1 );
-+  testcase( iB==-1 ); testcase( iB==0 );
-+  if( iB>=0 ){
-+    testcase( iA>0 && LARGEST_INT64 - iA == iB );
-+    testcase( iA>0 && LARGEST_INT64 - iA == iB - 1 );
-+    if( iA>0 && LARGEST_INT64 - iA < iB ) return 1;
-+    *pA += iB;
-+  }else{
-+    testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 1 );
-+    testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 2 );
-+    if( iA<0 && -(iA + LARGEST_INT64) > iB + 1 ) return 1;
-+    *pA += iB;
-   }
--  pInode->pUnused = 0;
-+  return 0; 
-+}
-+SQLITE_PRIVATE int sqlite3SubInt64(i64 *pA, i64 iB){
-+  testcase( iB==SMALLEST_INT64+1 );
-+  if( iB==SMALLEST_INT64 ){
-+    testcase( (*pA)==(-1) ); testcase( (*pA)==0 );
-+    if( (*pA)>=0 ) return 1;
-+    *pA -= iB;
-+    return 0;
-+  }else{
-+    return sqlite3AddInt64(pA, -iB);
-+  }
-+}
-+#define TWOPOWER32 (((i64)1)<<32)
-+#define TWOPOWER31 (((i64)1)<<31)
-+SQLITE_PRIVATE int sqlite3MulInt64(i64 *pA, i64 iB){
-+  i64 iA = *pA;
-+  i64 iA1, iA0, iB1, iB0, r;
-+
-+  iA1 = iA/TWOPOWER32;
-+  iA0 = iA % TWOPOWER32;
-+  iB1 = iB/TWOPOWER32;
-+  iB0 = iB % TWOPOWER32;
-+  if( iA1*iB1 != 0 ) return 1;
-+  assert( iA1*iB0==0 || iA0*iB1==0 );
-+  r = iA1*iB0 + iA0*iB1;
-+  testcase( r==(-TWOPOWER31)-1 );
-+  testcase( r==(-TWOPOWER31) );
-+  testcase( r==TWOPOWER31 );
-+  testcase( r==TWOPOWER31-1 );
-+  if( r<(-TWOPOWER31) || r>=TWOPOWER31 ) return 1;
-+  r *= TWOPOWER32;
-+  if( sqlite3AddInt64(&r, iA0*iB0) ) return 1;
-+  *pA = r;
-+  return 0;
- }
- 
- /*
--** Release a unixInodeInfo structure previously allocated by findInodeInfo().
-+** Compute the absolute value of a 32-bit signed integer, of possible.  Or 
-+** if the integer has a value of -2147483648, return +2147483647
-+*/
-+SQLITE_PRIVATE int sqlite3AbsInt32(int x){
-+  if( x>=0 ) return x;
-+  if( x==(int)0x80000000 ) return 0x7fffffff;
-+  return -x;
-+}
-+
-+#ifdef SQLITE_ENABLE_8_3_NAMES
-+/*
-+** If SQLITE_ENABLE_8_3_NAMES is set at compile-time and if the database
-+** filename in zBaseFilename is a URI with the "8_3_names=1" parameter and
-+** if filename in z[] has a suffix (a.k.a. "extension") that is longer than
-+** three characters, then shorten the suffix on z[] to be the last three
-+** characters of the original suffix.
- **
--** The mutex entered using the unixEnterMutex() function must be held
--** when this function is called.
-+** If SQLITE_ENABLE_8_3_NAMES is set to 2 at compile-time, then always
-+** do the suffix shortening regardless of URI parameter.
-+**
-+** Examples:
-+**
-+**     test.db-journal    =>   test.nal
-+**     test.db-wal        =>   test.wal
-+**     test.db-shm        =>   test.shm
-+**     test.db-mj7f3319fa =>   test.9fa
- */
--static void releaseInodeInfo(unixFile *pFile){
--  unixInodeInfo *pInode = pFile->pInode;
--  assert( unixMutexHeld() );
--  if( ALWAYS(pInode) ){
--    pInode->nRef--;
--    if( pInode->nRef==0 ){
--      assert( pInode->pShmNode==0 );
--      closePendingFds(pFile);
--      if( pInode->pPrev ){
--        assert( pInode->pPrev->pNext==pInode );
--        pInode->pPrev->pNext = pInode->pNext;
--      }else{
--        assert( inodeList==pInode );
--        inodeList = pInode->pNext;
--      }
--      if( pInode->pNext ){
--        assert( pInode->pNext->pPrev==pInode );
--        pInode->pNext->pPrev = pInode->pPrev;
--      }
--      sqlite3_free(pInode);
--    }
-+SQLITE_PRIVATE void sqlite3FileSuffix3(const char *zBaseFilename, char *z){
-+#if SQLITE_ENABLE_8_3_NAMES<2
-+  if( sqlite3_uri_boolean(zBaseFilename, "8_3_names", 0) )
-+#endif
-+  {
-+    int i, sz;
-+    sz = sqlite3Strlen30(z);
-+    for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){}
-+    if( z[i]=='.' && ALWAYS(sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4);
-   }
- }
-+#endif
- 
-+/************** End of util.c ************************************************/
-+/************** Begin file hash.c ********************************************/
- /*
--** Given a file descriptor, locate the unixInodeInfo object that
--** describes that file descriptor.  Create a new one if necessary.  The
--** return value might be uninitialized if an error occurs.
-+** 2001 September 22
- **
--** The mutex entered using the unixEnterMutex() function 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:
- **
--** Return an appropriate error code.
-+**    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 generic hash-tables
-+** used in SQLite.
- */
--static int findInodeInfo(
--  unixFile *pFile,               /* Unix file with file desc used in the key */
--  unixInodeInfo **ppInode        /* Return the unixInodeInfo object here */
--){
--  int rc;                        /* System call return code */
--  int fd;                        /* The file descriptor for pFile */
--  struct unixFileId fileId;      /* Lookup key for the unixInodeInfo */
--  struct stat statbuf;           /* Low-level file information */
--  unixInodeInfo *pInode = 0;     /* Candidate unixInodeInfo object */
-+/* #include <assert.h> */
- 
--  assert( unixMutexHeld() );
-+/* Turn bulk memory into a hash table object by initializing the
-+** fields of the Hash structure.
-+**
-+** "pNew" is a pointer to the hash table that is to be initialized.
-+*/
-+SQLITE_PRIVATE void sqlite3HashInit(Hash *pNew){
-+  assert( pNew!=0 );
-+  pNew->first = 0;
-+  pNew->count = 0;
-+  pNew->htsize = 0;
-+  pNew->ht = 0;
-+}
- 
--  /* Get low-level information about the file that we can used to
--  ** create a unique name for the file.
--  */
--  fd = pFile->h;
--  rc = osFstat(fd, &statbuf);
--  if( rc!=0 ){
--    pFile->lastErrno = errno;
--#ifdef EOVERFLOW
--    if( pFile->lastErrno==EOVERFLOW ) return SQLITE_NOLFS;
--#endif
--    return SQLITE_IOERR;
--  }
-+/* Remove all entries from a hash table.  Reclaim all memory.
-+** Call this routine to delete a hash table or to reset a hash table
-+** to the empty state.
-+*/
-+SQLITE_PRIVATE void sqlite3HashClear(Hash *pH){
-+  HashElem *elem;         /* For looping over all elements of the table */
- 
--#ifdef __APPLE__
--  /* On OS X on an msdos filesystem, the inode number is reported
--  ** incorrectly for zero-size files.  See ticket #3260.  To work
--  ** around this problem (we consider it a bug in OS X, not SQLite)
--  ** we always increase the file size to 1 by writing a single byte
--  ** prior to accessing the inode number.  The one byte written is
--  ** an ASCII 'S' character which also happens to be the first byte
--  ** in the header of every SQLite database.  In this way, if there
--  ** is a race condition such that another thread has already populated
--  ** the first page of the database, no damage is done.
--  */
--  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;
--      return SQLITE_IOERR;
--    }
--    rc = osFstat(fd, &statbuf);
--    if( rc!=0 ){
--      pFile->lastErrno = errno;
--      return SQLITE_IOERR;
--    }
-+  assert( pH!=0 );
-+  elem = pH->first;
-+  pH->first = 0;
-+  sqlite3_free(pH->ht);
-+  pH->ht = 0;
-+  pH->htsize = 0;
-+  while( elem ){
-+    HashElem *next_elem = elem->next;
-+    sqlite3_free(elem);
-+    elem = next_elem;
-   }
--#endif
-+  pH->count = 0;
-+}
- 
--  memset(&fileId, 0, sizeof(fileId));
--  fileId.dev = statbuf.st_dev;
--#if OS_VXWORKS
--  fileId.pId = pFile->pId;
--#else
--  fileId.ino = statbuf.st_ino;
--#endif
--  pInode = inodeList;
--  while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){
--    pInode = pInode->pNext;
--  }
--  if( pInode==0 ){
--    pInode = sqlite3_malloc( sizeof(*pInode) );
--    if( pInode==0 ){
--      return SQLITE_NOMEM;
--    }
--    memset(pInode, 0, sizeof(*pInode));
--    memcpy(&pInode->fileId, &fileId, sizeof(fileId));
--    pInode->nRef = 1;
--    pInode->pNext = inodeList;
--    pInode->pPrev = 0;
--    if( inodeList ) inodeList->pPrev = pInode;
--    inodeList = pInode;
--  }else{
--    pInode->nRef++;
-+/*
-+** The hashing function.
-+*/
-+static unsigned int strHash(const char *z, int nKey){
-+  int h = 0;
-+  assert( nKey>=0 );
-+  while( nKey > 0  ){
-+    h = (h<<3) ^ h ^ sqlite3UpperToLower[(unsigned char)*z++];
-+    nKey--;
-   }
--  *ppInode = pInode;
--  return SQLITE_OK;
-+  return h;
- }
- 
- 
--/*
--** Check a unixFile that is a database.  Verify the following:
--**
--** (1) There is exactly one hard link on the file
--** (2) The file is not a symbolic link
--** (3) The file has not been renamed or unlinked
--**
--** Issue sqlite3_log(SQLITE_WARNING,...) messages if anything is not right.
-+/* Link pNew element into the hash table pH.  If pEntry!=0 then also
-+** insert pNew into the pEntry hash bucket.
- */
--static void verifyDbFile(unixFile *pFile){
--  struct stat buf;
--  int rc;
--  if( pFile->ctrlFlags & UNIXFILE_WARNED ){
--    /* One or more of the following warnings have already been issued.  Do not
--    ** repeat them so as not to clutter the error log */
--    return;
--  }
--  rc = osFstat(pFile->h, &buf);
--  if( rc!=0 ){
--    sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath);
--    pFile->ctrlFlags |= UNIXFILE_WARNED;
--    return;
--  }
--  if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){
--    sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath);
--    pFile->ctrlFlags |= UNIXFILE_WARNED;
--    return;
--  }
--  if( buf.st_nlink>1 ){
--    sqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath);
--    pFile->ctrlFlags |= UNIXFILE_WARNED;
--    return;
-+static void insertElement(
-+  Hash *pH,              /* The complete hash table */
-+  struct _ht *pEntry,    /* The entry into which pNew is inserted */
-+  HashElem *pNew         /* The element to be inserted */
-+){
-+  HashElem *pHead;       /* First element already in pEntry */
-+  if( pEntry ){
-+    pHead = pEntry->count ? pEntry->chain : 0;
-+    pEntry->count++;
-+    pEntry->chain = pNew;
-+  }else{
-+    pHead = 0;
-   }
--  if( pFile->pInode!=0
--   && ((rc = osStat(pFile->zPath, &buf))!=0
--       || buf.st_ino!=pFile->pInode->fileId.ino)
--  ){
--    sqlite3_log(SQLITE_WARNING, "file renamed while open: %s", pFile->zPath);
--    pFile->ctrlFlags |= UNIXFILE_WARNED;
--    return;
-+  if( pHead ){
-+    pNew->next = pHead;
-+    pNew->prev = pHead->prev;
-+    if( pHead->prev ){ pHead->prev->next = pNew; }
-+    else             { pH->first = pNew; }
-+    pHead->prev = pNew;
-+  }else{
-+    pNew->next = pH->first;
-+    if( pH->first ){ pH->first->prev = pNew; }
-+    pNew->prev = 0;
-+    pH->first = pNew;
-   }
- }
- 
- 
--/*
--** 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, set *pResOut
--** 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.
-+/* Resize the hash table so that it cantains "new_size" buckets.
-+**
-+** The hash table might fail to resize if sqlite3_malloc() fails or
-+** if the new size is the same as the prior size.
-+** Return TRUE if the resize occurs and false if not.
- */
--static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
--  int rc = SQLITE_OK;
--  int reserved = 0;
--  unixFile *pFile = (unixFile*)id;
-+static int rehash(Hash *pH, unsigned int new_size){
-+  struct _ht *new_ht;            /* The new hash table */
-+  HashElem *elem, *next_elem;    /* For looping over existing elements */
- 
--  SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
-+#if SQLITE_MALLOC_SOFT_LIMIT>0
-+  if( new_size*sizeof(struct _ht)>SQLITE_MALLOC_SOFT_LIMIT ){
-+    new_size = SQLITE_MALLOC_SOFT_LIMIT/sizeof(struct _ht);
-+  }
-+  if( new_size==pH->htsize ) return 0;
-+#endif
- 
--  assert( pFile );
--  unixEnterMutex(); /* Because pFile->pInode is shared across threads */
-+  /* The inability to allocates space for a larger hash table is
-+  ** a performance hit but it is not a fatal error.  So mark the
-+  ** allocation as a benign. Use sqlite3Malloc()/memset(0) instead of 
-+  ** sqlite3MallocZero() to make the allocation, as sqlite3MallocZero()
-+  ** only zeroes the requested number of bytes whereas this module will
-+  ** use the actual amount of space allocated for the hash table (which
-+  ** may be larger than the requested amount).
-+  */
-+  sqlite3BeginBenignMalloc();
-+  new_ht = (struct _ht *)sqlite3Malloc( new_size*sizeof(struct _ht) );
-+  sqlite3EndBenignMalloc();
- 
--  /* Check if a thread in this process holds such a lock */
--  if( pFile->pInode->eFileLock>SHARED_LOCK ){
--    reserved = 1;
-+  if( new_ht==0 ) return 0;
-+  sqlite3_free(pH->ht);
-+  pH->ht = new_ht;
-+  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;
-+    next_elem = elem->next;
-+    insertElement(pH, &new_ht[h], elem);
-   }
-+  return 1;
-+}
- 
--  /* Otherwise see if some other process holds it.
--  */
--#ifndef __DJGPP__
--  if( !reserved && !pFile->pInode->bProcessLock ){
--    struct flock lock;
--    lock.l_whence = SEEK_SET;
--    lock.l_start = RESERVED_BYTE;
--    lock.l_len = 1;
--    lock.l_type = F_WRLCK;
--    if( osFcntl(pFile->h, F_GETLK, &lock) ){
--      rc = SQLITE_IOERR_CHECKRESERVEDLOCK;
--      pFile->lastErrno = errno;
--    } else if( lock.l_type!=F_UNLCK ){
--      reserved = 1;
-+/* 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.
-+*/
-+static HashElem *findElementGivenHash(
-+  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. */
-+){
-+  HashElem *elem;                /* Used to loop thru the element list */
-+  int count;                     /* Number of elements left to test */
-+
-+  if( pH->ht ){
-+    struct _ht *pEntry = &pH->ht[h];
-+    elem = pEntry->chain;
-+    count = pEntry->count;
-+  }else{
-+    elem = pH->first;
-+    count = pH->count;
-+  }
-+  while( count-- && ALWAYS(elem) ){
-+    if( elem->nKey==nKey && sqlite3StrNICmp(elem->pKey,pKey,nKey)==0 ){ 
-+      return elem;
-     }
-+    elem = elem->next;
-   }
--#endif
--  
--  unixLeaveMutex();
--  OSTRACE(("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved));
--
--  *pResOut = reserved;
--  return rc;
-+  return 0;
- }
- 
--/*
--** Attempt to set a system-lock on the file pFile.  The lock is 
--** described by pLock.
--**
--** If the pFile was opened read/write from unix-excl, then the only lock
--** ever obtained is an exclusive lock, and it is obtained exactly once
--** the first time any lock is attempted.  All subsequent system locking
--** operations become no-ops.  Locking operations still happen internally,
--** in order to coordinate access between separate database connections
--** within this process, but all of that is handled in memory and the
--** operating system does not participate.
--**
--** This function is a pass-through to fcntl(F_SETLK) if pFile is using
--** any VFS other than "unix-excl" or if pFile is opened on "unix-excl"
--** and is read-only.
--**
--** Zero is returned if the call completes successfully, or -1 if a call
--** to fcntl() fails. In this case, errno is set appropriately (by fcntl()).
-+/* Remove a single entry from the hash table given a pointer to that
-+** element and a hash on the element's key.
- */
--static int unixFileLock(unixFile *pFile, struct flock *pLock){
--  int rc;
--  unixInodeInfo *pInode = pFile->pInode;
--  assert( unixMutexHeld() );
--  assert( pInode!=0 );
--  if( ((pFile->ctrlFlags & UNIXFILE_EXCL)!=0 || pInode->bProcessLock)
--   && ((pFile->ctrlFlags & UNIXFILE_RDONLY)==0)
--  ){
--    if( pInode->bProcessLock==0 ){
--      struct flock lock;
--      assert( pInode->nLock==0 );
--      lock.l_whence = SEEK_SET;
--      lock.l_start = SHARED_FIRST;
--      lock.l_len = SHARED_SIZE;
--      lock.l_type = F_WRLCK;
--      rc = osFcntl(pFile->h, F_SETLK, &lock);
--      if( rc<0 ) return rc;
--      pInode->bProcessLock = 1;
--      pInode->nLock++;
--    }else{
--      rc = 0;
-+static void removeElementGivenHash(
-+  Hash *pH,         /* The pH containing "elem" */
-+  HashElem* elem,   /* The element to be removed from the pH */
-+  unsigned int h    /* Hash value for the element */
-+){
-+  struct _ht *pEntry;
-+  if( elem->prev ){
-+    elem->prev->next = elem->next; 
-+  }else{
-+    pH->first = elem->next;
-+  }
-+  if( elem->next ){
-+    elem->next->prev = elem->prev;
-+  }
-+  if( pH->ht ){
-+    pEntry = &pH->ht[h];
-+    if( pEntry->chain==elem ){
-+      pEntry->chain = elem->next;
-     }
-+    pEntry->count--;
-+    assert( pEntry->count>=0 );
-+  }
-+  sqlite3_free( elem );
-+  pH->count--;
-+  if( pH->count==0 ){
-+    assert( pH->first==0 );
-+    assert( pH->count==0 );
-+    sqlite3HashClear(pH);
-+  }
-+}
-+
-+/* 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
-+** found, or NULL if there is no match.
-+*/
-+SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey, int nKey){
-+  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{
--    rc = osFcntl(pFile->h, F_SETLK, pLock);
-+    h = 0;
-   }
--  return rc;
-+  elem = findElementGivenHash(pH, pKey, nKey, h);
-+  return elem ? elem->data : 0;
- }
- 
--/*
--** Lock the file with the lock specified by parameter eFileLock - one
--** of the following:
--**
--**     (1) SHARED_LOCK
--**     (2) RESERVED_LOCK
--**     (3) PENDING_LOCK
--**     (4) EXCLUSIVE_LOCK
-+/* Insert an element into the hash table pH.  The key is pKey,nKey
-+** and the data is "data".
- **
--** 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:
-+** If no element exists with a matching key, then a new
-+** element is created and NULL is returned.
- **
--**    UNLOCKED -> SHARED
--**    SHARED -> RESERVED
--**    SHARED -> (PENDING) -> EXCLUSIVE
--**    RESERVED -> (PENDING) -> EXCLUSIVE
--**    PENDING -> EXCLUSIVE
-+** If another element already exists with the same key, then the
-+** new data replaces the old data and the old data is returned.
-+** The key is not copied in this instance.  If a malloc fails, then
-+** the new data is returned and the hash table is unchanged.
- **
--** This routine will only increase a lock.  Use the sqlite3OsUnlock()
--** routine to lower a locking level.
-+** If the "data" parameter to this function is NULL, then the
-+** element corresponding to "key" is removed from the hash table.
- */
--static int unixLock(sqlite3_file *id, int eFileLock){
--  /* The following describes the implementation of the various locks and
--  ** lock transitions in terms of the POSIX advisory shared and exclusive
--  ** lock primitives (called read-locks and write-locks below, to avoid
--  ** confusion with SQLite lock names). The algorithms are complicated
--  ** slightly in order to be compatible with windows systems simultaneously
--  ** accessing the same database file, in case that is ever required.
--  **
--  ** Symbols defined in os.h indentify the 'pending byte' and the 'reserved
--  ** byte', each single bytes at well known offsets, and the 'shared byte
--  ** range', a range of 510 bytes at a well known offset.
--  **
--  ** To obtain a SHARED lock, a read-lock is obtained on the 'pending
--  ** byte'.  If this is successful, a random byte from the 'shared byte
--  ** range' is read-locked and the lock on the 'pending byte' released.
--  **
--  ** A process may only obtain a RESERVED lock after it has a SHARED lock.
--  ** A RESERVED lock is implemented by grabbing a write-lock on the
--  ** 'reserved byte'. 
--  **
--  ** A process may only obtain a PENDING lock after it has obtained a
--  ** SHARED lock. A PENDING lock is implemented by obtaining a write-lock
--  ** on the 'pending byte'. This ensures that no new SHARED locks can be
--  ** obtained, but existing SHARED locks are allowed to persist. A process
--  ** does not have to obtain a RESERVED lock on the way to a PENDING lock.
--  ** This property is used by the algorithm for rolling back a journal file
--  ** after a crash.
--  **
--  ** An EXCLUSIVE lock, obtained after a PENDING lock is held, is
--  ** implemented by obtaining a write-lock on the entire 'shared byte
--  ** range'. Since all other locks require a read-lock on one of the bytes
--  ** within this range, this ensures that no other locks are held on the
--  ** database. 
--  **
--  ** The reason a single byte cannot be used instead of the 'shared byte
--  ** range' is that some versions of windows do not support read-locks. By
--  ** locking a random byte from a range, concurrent SHARED locks may exist
--  ** even if the locking primitive used is always a write-lock.
--  */
--  int rc = SQLITE_OK;
--  unixFile *pFile = (unixFile*)id;
--  unixInodeInfo *pInode;
--  struct flock lock;
--  int tErrno = 0;
--
--  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()));
-+SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, int nKey, 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 */
- 
--  /* 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
--  ** unixEnterMutex() hasn't been called yet.
--  */
--  if( pFile->eFileLock>=eFileLock ){
--    OSTRACE(("LOCK    %d %s ok (already held) (unix)\n", pFile->h,
--            azFileLock(eFileLock)));
--    return SQLITE_OK;
-+  assert( pH!=0 );
-+  assert( pKey!=0 );
-+  assert( nKey>=0 );
-+  if( pH->htsize ){
-+    h = strHash(pKey, nKey) % pH->htsize;
-+  }else{
-+    h = 0;
-   }
--
--  /* Make sure the locking sequence is correct.
--  **  (1) We never move from unlocked to anything higher than shared lock.
--  **  (2) SQLite never explicitly requests a pendig lock.
--  **  (3) A shared lock is always held when a reserve lock is requested.
--  */
--  assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK );
--  assert( eFileLock!=PENDING_LOCK );
--  assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK );
--
--  /* This mutex is needed because pFile->pInode is shared across threads
--  */
--  unixEnterMutex();
--  pInode = pFile->pInode;
--
--  /* If some thread using this PID has a lock via a different unixFile*
--  ** handle that precludes the requested lock, return BUSY.
--  */
--  if( (pFile->eFileLock!=pInode->eFileLock && 
--          (pInode->eFileLock>=PENDING_LOCK || eFileLock>SHARED_LOCK))
--  ){
--    rc = SQLITE_BUSY;
--    goto end_lock;
-+  elem = findElementGivenHash(pH,pKey,nKey,h);
-+  if( elem ){
-+    void *old_data = elem->data;
-+    if( data==0 ){
-+      removeElementGivenHash(pH,elem,h);
-+    }else{
-+      elem->data = data;
-+      elem->pKey = pKey;
-+      assert(nKey==elem->nKey);
-+    }
-+    return old_data;
-   }
--
--  /* If a SHARED lock is requested, and some thread using this PID already
--  ** has a SHARED or RESERVED lock, then increment reference counts and
--  ** return SQLITE_OK.
--  */
--  if( eFileLock==SHARED_LOCK && 
--      (pInode->eFileLock==SHARED_LOCK || pInode->eFileLock==RESERVED_LOCK) ){
--    assert( eFileLock==SHARED_LOCK );
--    assert( pFile->eFileLock==0 );
--    assert( pInode->nShared>0 );
--    pFile->eFileLock = SHARED_LOCK;
--    pInode->nShared++;
--    pInode->nLock++;
--    goto end_lock;
-+  if( data==0 ) return 0;
-+  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;
-+    }
-+  }
-+  if( pH->ht ){
-+    insertElement(pH, &pH->ht[h], new_elem);
-+  }else{
-+    insertElement(pH, 0, new_elem);
-   }
-+  return 0;
-+}
- 
-+/************** End of hash.c ************************************************/
-+/************** Begin file opcodes.c *****************************************/
-+/* Automatically generated.  Do not edit */
-+/* See the mkopcodec.awk script for details. */
-+#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
-+SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
-+ static const char *const azName[] = { "?",
-+     /*   1 */ "Goto",
-+     /*   2 */ "Gosub",
-+     /*   3 */ "Return",
-+     /*   4 */ "Yield",
-+     /*   5 */ "HaltIfNull",
-+     /*   6 */ "Halt",
-+     /*   7 */ "Integer",
-+     /*   8 */ "Int64",
-+     /*   9 */ "String",
-+     /*  10 */ "Null",
-+     /*  11 */ "Blob",
-+     /*  12 */ "Variable",
-+     /*  13 */ "Move",
-+     /*  14 */ "Copy",
-+     /*  15 */ "SCopy",
-+     /*  16 */ "ResultRow",
-+     /*  17 */ "CollSeq",
-+     /*  18 */ "Function",
-+     /*  19 */ "Not",
-+     /*  20 */ "AddImm",
-+     /*  21 */ "MustBeInt",
-+     /*  22 */ "RealAffinity",
-+     /*  23 */ "Permutation",
-+     /*  24 */ "Compare",
-+     /*  25 */ "Jump",
-+     /*  26 */ "Once",
-+     /*  27 */ "If",
-+     /*  28 */ "IfNot",
-+     /*  29 */ "Column",
-+     /*  30 */ "Affinity",
-+     /*  31 */ "MakeRecord",
-+     /*  32 */ "Count",
-+     /*  33 */ "Savepoint",
-+     /*  34 */ "AutoCommit",
-+     /*  35 */ "Transaction",
-+     /*  36 */ "ReadCookie",
-+     /*  37 */ "SetCookie",
-+     /*  38 */ "VerifyCookie",
-+     /*  39 */ "OpenRead",
-+     /*  40 */ "OpenWrite",
-+     /*  41 */ "OpenAutoindex",
-+     /*  42 */ "OpenEphemeral",
-+     /*  43 */ "SorterOpen",
-+     /*  44 */ "OpenPseudo",
-+     /*  45 */ "Close",
-+     /*  46 */ "SeekLt",
-+     /*  47 */ "SeekLe",
-+     /*  48 */ "SeekGe",
-+     /*  49 */ "SeekGt",
-+     /*  50 */ "Seek",
-+     /*  51 */ "NotFound",
-+     /*  52 */ "Found",
-+     /*  53 */ "IsUnique",
-+     /*  54 */ "NotExists",
-+     /*  55 */ "Sequence",
-+     /*  56 */ "NewRowid",
-+     /*  57 */ "Insert",
-+     /*  58 */ "InsertInt",
-+     /*  59 */ "Delete",
-+     /*  60 */ "ResetCount",
-+     /*  61 */ "SorterCompare",
-+     /*  62 */ "SorterData",
-+     /*  63 */ "RowKey",
-+     /*  64 */ "RowData",
-+     /*  65 */ "Rowid",
-+     /*  66 */ "NullRow",
-+     /*  67 */ "Last",
-+     /*  68 */ "Or",
-+     /*  69 */ "And",
-+     /*  70 */ "SorterSort",
-+     /*  71 */ "Sort",
-+     /*  72 */ "Rewind",
-+     /*  73 */ "IsNull",
-+     /*  74 */ "NotNull",
-+     /*  75 */ "Ne",
-+     /*  76 */ "Eq",
-+     /*  77 */ "Gt",
-+     /*  78 */ "Le",
-+     /*  79 */ "Lt",
-+     /*  80 */ "Ge",
-+     /*  81 */ "SorterNext",
-+     /*  82 */ "BitAnd",
-+     /*  83 */ "BitOr",
-+     /*  84 */ "ShiftLeft",
-+     /*  85 */ "ShiftRight",
-+     /*  86 */ "Add",
-+     /*  87 */ "Subtract",
-+     /*  88 */ "Multiply",
-+     /*  89 */ "Divide",
-+     /*  90 */ "Remainder",
-+     /*  91 */ "Concat",
-+     /*  92 */ "Prev",
-+     /*  93 */ "BitNot",
-+     /*  94 */ "String8",
-+     /*  95 */ "Next",
-+     /*  96 */ "SorterInsert",
-+     /*  97 */ "IdxInsert",
-+     /*  98 */ "IdxDelete",
-+     /*  99 */ "IdxRowid",
-+     /* 100 */ "IdxLT",
-+     /* 101 */ "IdxGE",
-+     /* 102 */ "Destroy",
-+     /* 103 */ "Clear",
-+     /* 104 */ "CreateIndex",
-+     /* 105 */ "CreateTable",
-+     /* 106 */ "ParseSchema",
-+     /* 107 */ "LoadAnalysis",
-+     /* 108 */ "DropTable",
-+     /* 109 */ "DropIndex",
-+     /* 110 */ "DropTrigger",
-+     /* 111 */ "IntegrityCk",
-+     /* 112 */ "RowSetAdd",
-+     /* 113 */ "RowSetRead",
-+     /* 114 */ "RowSetTest",
-+     /* 115 */ "Program",
-+     /* 116 */ "Param",
-+     /* 117 */ "FkCounter",
-+     /* 118 */ "FkIfZero",
-+     /* 119 */ "MemMax",
-+     /* 120 */ "IfPos",
-+     /* 121 */ "IfNeg",
-+     /* 122 */ "IfZero",
-+     /* 123 */ "AggStep",
-+     /* 124 */ "AggFinal",
-+     /* 125 */ "Checkpoint",
-+     /* 126 */ "JournalMode",
-+     /* 127 */ "Vacuum",
-+     /* 128 */ "IncrVacuum",
-+     /* 129 */ "Expire",
-+     /* 130 */ "Real",
-+     /* 131 */ "TableLock",
-+     /* 132 */ "VBegin",
-+     /* 133 */ "VCreate",
-+     /* 134 */ "VDestroy",
-+     /* 135 */ "VOpen",
-+     /* 136 */ "VFilter",
-+     /* 137 */ "VColumn",
-+     /* 138 */ "VNext",
-+     /* 139 */ "VRename",
-+     /* 140 */ "VUpdate",
-+     /* 141 */ "ToText",
-+     /* 142 */ "ToBlob",
-+     /* 143 */ "ToNumeric",
-+     /* 144 */ "ToInt",
-+     /* 145 */ "ToReal",
-+     /* 146 */ "Pagecount",
-+     /* 147 */ "MaxPgcnt",
-+     /* 148 */ "Trace",
-+     /* 149 */ "Noop",
-+     /* 150 */ "Explain",
-+  };
-+  return azName[i];
-+}
-+#endif
- 
--  /* A PENDING lock is needed before acquiring a SHARED lock and before
--  ** acquiring an EXCLUSIVE lock.  For the SHARED lock, the PENDING will
--  ** be released.
--  */
--  lock.l_len = 1L;
--  lock.l_whence = SEEK_SET;
--  if( eFileLock==SHARED_LOCK 
--      || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLock<PENDING_LOCK)
--  ){
--    lock.l_type = (eFileLock==SHARED_LOCK?F_RDLCK:F_WRLCK);
--    lock.l_start = PENDING_BYTE;
--    if( unixFileLock(pFile, &lock) ){
--      tErrno = errno;
--      rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
--      if( rc!=SQLITE_BUSY ){
--        pFile->lastErrno = tErrno;
--      }
--      goto end_lock;
--    }
--  }
-+/************** End of opcodes.c *********************************************/
-+/************** Begin file os_unix.c *****************************************/
-+/*
-+** 2004 May 22
-+**
-+** 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 VFS implementation for unix-like operating systems
-+** include Linux, MacOSX, *BSD, QNX, VxWorks, AIX, HPUX, and others.
-+**
-+** There are actually several different VFS implementations in this file.
-+** The differences are in the way that file locking is done.  The default
-+** implementation uses Posix Advisory Locks.  Alternative implementations
-+** use flock(), dot-files, various proprietary locking schemas, or simply
-+** skip locking all together.
-+**
-+** This source file is organized into divisions where the logic for various
-+** subfunctions is contained within the appropriate division.  PLEASE
-+** KEEP THE STRUCTURE OF THIS FILE INTACT.  New code should be placed
-+** in the correct division and should be clearly labeled.
-+**
-+** The layout of divisions is as follows:
-+**
-+**   *  General-purpose declarations and utility functions.
-+**   *  Unique file ID logic used by VxWorks.
-+**   *  Various locking primitive implementations (all except proxy locking):
-+**      + for Posix Advisory Locks
-+**      + for no-op locks
-+**      + for dot-file locks
-+**      + for flock() locking
-+**      + for named semaphore locks (VxWorks only)
-+**      + for AFP filesystem locks (MacOSX only)
-+**   *  sqlite3_file methods not associated with locking.
-+**   *  Definitions of sqlite3_io_methods objects for all locking
-+**      methods plus "finder" functions for each locking method.
-+**   *  sqlite3_vfs method implementations.
-+**   *  Locking primitives for the proxy uber-locking-method. (MacOSX only)
-+**   *  Definitions of sqlite3_vfs objects for all locking methods
-+**      plus implementations of sqlite3_os_init() and sqlite3_os_end().
-+*/
-+#if SQLITE_OS_UNIX              /* This file is used on unix only */
- 
-+/* Use posix_fallocate() if it is available
-+*/
-+#if !defined(HAVE_POSIX_FALLOCATE) \
-+      && (_XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L)
-+# define HAVE_POSIX_FALLOCATE 1
-+#endif
- 
--  /* If control gets to this point, then actually go ahead and make
--  ** operating system calls for the specified lock.
--  */
--  if( eFileLock==SHARED_LOCK ){
--    assert( pInode->nShared==0 );
--    assert( pInode->eFileLock==0 );
--    assert( rc==SQLITE_OK );
-+/*
-+** There are various methods for file locking used for concurrency
-+** control:
-+**
-+**   1. POSIX locking (the default),
-+**   2. No locking,
-+**   3. Dot-file locking,
-+**   4. flock() locking,
-+**   5. AFP locking (OSX only),
-+**   6. Named POSIX semaphores (VXWorks only),
-+**   7. proxy locking. (OSX only)
-+**
-+** Styles 4, 5, and 7 are only available of SQLITE_ENABLE_LOCKING_STYLE
-+** is defined to 1.  The SQLITE_ENABLE_LOCKING_STYLE also enables automatic
-+** selection of the appropriate locking style based on the filesystem
-+** where the database is located.  
-+*/
-+#if !defined(SQLITE_ENABLE_LOCKING_STYLE)
-+#  if defined(__APPLE__)
-+#    define SQLITE_ENABLE_LOCKING_STYLE 1
-+#  else
-+#    define SQLITE_ENABLE_LOCKING_STYLE 0
-+#  endif
-+#endif
- 
--    /* Now get the read-lock */
--    lock.l_start = SHARED_FIRST;
--    lock.l_len = SHARED_SIZE;
--    if( unixFileLock(pFile, &lock) ){
--      tErrno = errno;
--      rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
--    }
-+/*
-+** 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
- 
--    /* Drop the temporary PENDING lock */
--    lock.l_start = PENDING_BYTE;
--    lock.l_len = 1L;
--    lock.l_type = F_UNLCK;
--    if( unixFileLock(pFile, &lock) && rc==SQLITE_OK ){
--      /* This could happen with a network mount */
--      tErrno = errno;
--      rc = SQLITE_IOERR_UNLOCK; 
--    }
-+/*
-+** These #defines should enable >2GB file support on Posix if the
-+** underlying operating system supports it.  If the OS lacks
-+** large file support, these should be no-ops.
-+**
-+** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
-+** on the compiler command line.  This is necessary if you are compiling
-+** on a recent machine (ex: RedHat 7.2) but you want your code to work
-+** on an older machine (ex: RedHat 6.0).  If you compile on RedHat 7.2
-+** without this option, LFS is enable.  But LFS does not exist in the kernel
-+** in RedHat 6.0, so the code won't work.  Hence, for maximum binary
-+** portability you should omit LFS.
-+**
-+** The previous paragraph was written in 2005.  (This paragraph is written
-+** on 2008-11-28.) These days, all Linux kernels support large files, so
-+** you should probably leave LFS enabled.  But some embedded platforms might
-+** lack LFS in which case the SQLITE_DISABLE_LFS macro might still be useful.
-+*/
-+#ifndef SQLITE_DISABLE_LFS
-+# define _LARGE_FILE       1
-+# ifndef _FILE_OFFSET_BITS
-+#   define _FILE_OFFSET_BITS 64
-+# endif
-+# define _LARGEFILE_SOURCE 1
-+#endif
- 
--    if( rc ){
--      if( rc!=SQLITE_BUSY ){
--        pFile->lastErrno = tErrno;
--      }
--      goto end_lock;
--    }else{
--      pFile->eFileLock = SHARED_LOCK;
--      pInode->nLock++;
--      pInode->nShared = 1;
--    }
--  }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){
--    /* We are trying for an exclusive lock but another thread in this
--    ** same process is still holding a shared lock. */
--    rc = SQLITE_BUSY;
--  }else{
--    /* The request was for a RESERVED or EXCLUSIVE lock.  It is
--    ** assumed that there is a SHARED or greater lock on the file
--    ** already.
--    */
--    assert( 0!=pFile->eFileLock );
--    lock.l_type = F_WRLCK;
-+/*
-+** standard include files.
-+*/
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
-+#include <unistd.h>
-+/* #include <time.h> */
-+#include <sys/time.h>
-+#include <errno.h>
-+#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
 +/* #include <sys/mman.h> */
-+#endif
- 
--    assert( eFileLock==RESERVED_LOCK || eFileLock==EXCLUSIVE_LOCK );
--    if( eFileLock==RESERVED_LOCK ){
--      lock.l_start = RESERVED_BYTE;
--      lock.l_len = 1L;
--    }else{
--      lock.l_start = SHARED_FIRST;
--      lock.l_len = SHARED_SIZE;
--    }
- 
--    if( unixFileLock(pFile, &lock) ){
--      tErrno = errno;
--      rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
--      if( rc!=SQLITE_BUSY ){
--        pFile->lastErrno = tErrno;
--      }
--    }
--  }
--  
-+#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
-+#endif /* SQLITE_ENABLE_LOCKING_STYLE */
- 
--#ifdef SQLITE_DEBUG
--  /* Set up the transaction-counter change checking flags when
--  ** transitioning from a SHARED to a RESERVED lock.  The change
--  ** from SHARED to RESERVED marks the beginning of a normal
--  ** write operation (not a hot journal rollback).
--  */
--  if( rc==SQLITE_OK
--   && pFile->eFileLock<=SHARED_LOCK
--   && eFileLock==RESERVED_LOCK
--  ){
--    pFile->transCntrChng = 0;
--    pFile->dbUpdate = 0;
--    pFile->inNormalWrite = 1;
--  }
-+#if defined(__APPLE__) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS)
-+# include <sys/mount.h>
- #endif
- 
--
--  if( rc==SQLITE_OK ){
--    pFile->eFileLock = eFileLock;
--    pInode->eFileLock = eFileLock;
--  }else if( eFileLock==EXCLUSIVE_LOCK ){
--    pFile->eFileLock = PENDING_LOCK;
--    pInode->eFileLock = PENDING_LOCK;
--  }
--
--end_lock:
--  unixLeaveMutex();
--  OSTRACE(("LOCK    %d %s %s (unix)\n", pFile->h, azFileLock(eFileLock), 
--      rc==SQLITE_OK ? "ok" : "failed"));
--  return rc;
--}
-+#ifdef HAVE_UTIME
-+# include <utime.h>
-+#endif
- 
- /*
--** Add the file descriptor used by file handle pFile to the corresponding
--** pUnused list.
-+** Allowed values of unixFile.fsFlags
- */
--static void setPendingFd(unixFile *pFile){
--  unixInodeInfo *pInode = pFile->pInode;
--  UnixUnusedFd *p = pFile->pUnused;
--  p->pNext = pInode->pUnused;
--  pInode->pUnused = p;
--  pFile->h = -1;
--  pFile->pUnused = 0;
--}
-+#define SQLITE_FSFLAGS_IS_MSDOS     0x1
- 
- /*
--** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
--** 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.
--** 
--** If handleNFSUnlock is true, then on downgrading an EXCLUSIVE_LOCK to SHARED
--** the byte range is divided into 2 parts and the first part is unlocked then
--** set to a read lock, then the other part is simply unlocked.  This works 
--** around a bug in BSD NFS lockd (also seen on MacOSX 10.3+) that fails to 
--** remove the write lock on a region when a read lock is set.
-+** If we are to be thread-safe, include the pthreads header and define
-+** the SQLITE_UNIX_THREADS macro.
- */
--static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
--  unixFile *pFile = (unixFile*)id;
--  unixInodeInfo *pInode;
--  struct flock lock;
--  int rc = SQLITE_OK;
--
--  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()));
--
--  assert( eFileLock<=SHARED_LOCK );
--  if( pFile->eFileLock<=eFileLock ){
--    return SQLITE_OK;
--  }
--  unixEnterMutex();
--  pInode = pFile->pInode;
--  assert( pInode->nShared!=0 );
--  if( pFile->eFileLock>SHARED_LOCK ){
--    assert( pInode->eFileLock==pFile->eFileLock );
--
--#ifdef SQLITE_DEBUG
--    /* When reducing a lock such that other processes can start
--    ** reading the database file again, make sure that the
--    ** transaction counter was updated if any part of the database
--    ** file changed.  If the transaction counter is not updated,
--    ** other connections to the same file might not realize that
--    ** the file has changed and hence might not know to flush their
--    ** cache.  The use of a stale cache can lead to database corruption.
--    */
--    pFile->inNormalWrite = 0;
-+#if SQLITE_THREADSAFE
-+/* # include <pthread.h> */
-+# define SQLITE_UNIX_THREADS 1
- #endif
- 
--    /* downgrading to a shared lock on NFS involves clearing the write lock
--    ** before establishing the readlock - to avoid a race condition we downgrade
--    ** the lock in 2 blocks, so that part of the range will be covered by a 
--    ** write lock until the rest is covered by a read lock:
--    **  1:   [WWWWW]
--    **  2:   [....W]
--    **  3:   [RRRRW]
--    **  4:   [RRRR.]
--    */
--    if( eFileLock==SHARED_LOCK ){
--
--#if !defined(__APPLE__) || !SQLITE_ENABLE_LOCKING_STYLE
--      (void)handleNFSUnlock;
--      assert( handleNFSUnlock==0 );
-+/*
-+** Default permissions when creating a new file
-+*/
-+#ifndef SQLITE_DEFAULT_FILE_PERMISSIONS
-+# define SQLITE_DEFAULT_FILE_PERMISSIONS 0644
- #endif
--#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
--      if( handleNFSUnlock ){
--        int tErrno;               /* Error code from system call errors */
--        off_t divSize = SHARED_SIZE - 1;
--        
--        lock.l_type = F_UNLCK;
--        lock.l_whence = SEEK_SET;
--        lock.l_start = SHARED_FIRST;
--        lock.l_len = divSize;
--        if( unixFileLock(pFile, &lock)==(-1) ){
--          tErrno = errno;
--          rc = SQLITE_IOERR_UNLOCK;
--          if( IS_LOCK_ERROR(rc) ){
--            pFile->lastErrno = tErrno;
--          }
--          goto end_unlock;
--        }
--        lock.l_type = F_RDLCK;
--        lock.l_whence = SEEK_SET;
--        lock.l_start = SHARED_FIRST;
--        lock.l_len = divSize;
--        if( unixFileLock(pFile, &lock)==(-1) ){
--          tErrno = errno;
--          rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK);
--          if( IS_LOCK_ERROR(rc) ){
--            pFile->lastErrno = tErrno;
--          }
--          goto end_unlock;
--        }
--        lock.l_type = F_UNLCK;
--        lock.l_whence = SEEK_SET;
--        lock.l_start = SHARED_FIRST+divSize;
--        lock.l_len = SHARED_SIZE-divSize;
--        if( unixFileLock(pFile, &lock)==(-1) ){
--          tErrno = errno;
--          rc = SQLITE_IOERR_UNLOCK;
--          if( IS_LOCK_ERROR(rc) ){
--            pFile->lastErrno = tErrno;
--          }
--          goto end_unlock;
--        }
--      }else
--#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
--      {
--        lock.l_type = F_RDLCK;
--        lock.l_whence = SEEK_SET;
--        lock.l_start = SHARED_FIRST;
--        lock.l_len = SHARED_SIZE;
--        if( unixFileLock(pFile, &lock) ){
--          /* In theory, the call to unixFileLock() cannot fail because another
--          ** process is holding an incompatible lock. If it does, this 
--          ** indicates that the other process is not following the locking
--          ** protocol. If this happens, return SQLITE_IOERR_RDLOCK. Returning
--          ** SQLITE_BUSY would confuse the upper layer (in practice it causes 
--          ** an assert to fail). */ 
--          rc = SQLITE_IOERR_RDLOCK;
--          pFile->lastErrno = errno;
--          goto end_unlock;
--        }
--      }
--    }
--    lock.l_type = F_UNLCK;
--    lock.l_whence = SEEK_SET;
--    lock.l_start = PENDING_BYTE;
--    lock.l_len = 2L;  assert( PENDING_BYTE+1==RESERVED_BYTE );
--    if( unixFileLock(pFile, &lock)==0 ){
--      pInode->eFileLock = SHARED_LOCK;
--    }else{
--      rc = SQLITE_IOERR_UNLOCK;
--      pFile->lastErrno = errno;
--      goto end_unlock;
--    }
--  }
--  if( eFileLock==NO_LOCK ){
--    /* Decrement the shared lock counter.  Release the lock using an
--    ** OS call only when all threads in this same process have released
--    ** the lock.
--    */
--    pInode->nShared--;
--    if( pInode->nShared==0 ){
--      lock.l_type = F_UNLCK;
--      lock.l_whence = SEEK_SET;
--      lock.l_start = lock.l_len = 0L;
--      if( unixFileLock(pFile, &lock)==0 ){
--        pInode->eFileLock = NO_LOCK;
--      }else{
--        rc = SQLITE_IOERR_UNLOCK;
--        pFile->lastErrno = errno;
--        pInode->eFileLock = NO_LOCK;
--        pFile->eFileLock = NO_LOCK;
--      }
--    }
--
--    /* Decrement the count of locks against this same file.  When the
--    ** count reaches zero, close any other file descriptors whose close
--    ** was deferred because of outstanding locks.
--    */
--    pInode->nLock--;
--    assert( pInode->nLock>=0 );
--    if( pInode->nLock==0 ){
--      closePendingFds(pFile);
--    }
--  }
--
--end_unlock:
--  unixLeaveMutex();
--  if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock;
--  return rc;
--}
- 
- /*
--** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
--** 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.
-+** Default permissions when creating auto proxy dir
- */
--static int unixUnlock(sqlite3_file *id, int eFileLock){
--  assert( eFileLock==SHARED_LOCK || ((unixFile *)id)->nFetchOut==0 );
--  return posixUnlock(id, eFileLock, 0);
--}
-+#ifndef SQLITE_DEFAULT_PROXYDIR_PERMISSIONS
-+# define SQLITE_DEFAULT_PROXYDIR_PERMISSIONS 0755
-+#endif
- 
--static int unixMapfile(unixFile *pFd, i64 nByte);
--static void unixUnmapfile(unixFile *pFd);
-+/*
-+** Maximum supported path-length.
-+*/
-+#define MAX_PATHNAME 512
- 
- /*
--** This function performs the parts of the "close file" operation 
--** common to all locking schemes. It closes the directory and file
--** handles, if they are valid, and sets all fields of the unixFile
--** structure to 0.
--**
--** It is *not* necessary to hold the mutex when this routine is called,
--** even on VxWorks.  A mutex will be acquired on VxWorks by the
--** vxworksReleaseFileId() routine.
-+** 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
- */
--static int closeUnixFile(sqlite3_file *id){
--  unixFile *pFile = (unixFile*)id;
--  unixUnmapfile(pFile);
--  if( pFile->h>=0 ){
--    robust_close(pFile, pFile->h, __LINE__);
--    pFile->h = -1;
--  }
--#if OS_VXWORKS
--  if( pFile->pId ){
--    if( pFile->ctrlFlags & UNIXFILE_DELETE ){
--      osUnlink(pFile->pId->zCanonicalName);
--    }
--    vxworksReleaseFileId(pFile->pId);
--    pFile->pId = 0;
--  }
--#endif
--  OSTRACE(("CLOSE   %-3d\n", pFile->h));
--  OpenCounter(-1);
--  sqlite3_free(pFile->pUnused);
--  memset(pFile, 0, sizeof(unixFile));
--  return SQLITE_OK;
--}
-+#define IS_LOCK_ERROR(x)  ((x != SQLITE_OK) && (x != SQLITE_BUSY))
-+
-+/* Forward references */
-+typedef struct unixShm unixShm;               /* Connection shared memory */
-+typedef struct unixShmNode unixShmNode;       /* Shared memory instance */
-+typedef struct unixInodeInfo unixInodeInfo;   /* An i-node */
-+typedef struct UnixUnusedFd UnixUnusedFd;     /* An unused file descriptor */
- 
- /*
--** Close a file.
-+** Sometimes, after a file handle is closed by SQLite, the file descriptor
-+** cannot be closed immediately. In these cases, instances of the following
-+** structure are used to store the file descriptor while waiting for an
-+** opportunity to either close or reuse it.
- */
--static int unixClose(sqlite3_file *id){
--  int rc = SQLITE_OK;
--  unixFile *pFile = (unixFile *)id;
--  verifyDbFile(pFile);
--  unixUnlock(id, NO_LOCK);
--  unixEnterMutex();
-+struct UnixUnusedFd {
-+  int fd;                   /* File descriptor to close */
-+  int flags;                /* Flags this file descriptor was opened with */
-+  UnixUnusedFd *pNext;      /* Next unused file descriptor on same file */
-+};
- 
--  /* unixFile.pInode is always valid here. Otherwise, a different close
--  ** routine (e.g. nolockClose()) would be called instead.
-+/*
-+** The unixFile structure is subclass of sqlite3_file specific to the unix
-+** VFS implementations.
-+*/
-+typedef struct unixFile unixFile;
-+struct unixFile {
-+  sqlite3_io_methods const *pMethod;  /* Always the first entry */
-+  sqlite3_vfs *pVfs;                  /* The VFS that created this unixFile */
-+  unixInodeInfo *pInode;              /* Info about locks on this inode */
-+  int h;                              /* The file descriptor */
-+  unsigned char eFileLock;            /* The type of lock held on this fd */
-+  unsigned short int ctrlFlags;       /* Behavioral bits.  UNIXFILE_* flags */
-+  int lastErrno;                      /* The unix errno from last I/O error */
-+  void *lockingContext;               /* Locking style specific state */
-+  UnixUnusedFd *pUnused;              /* Pre-allocated UnixUnusedFd */
-+  const char *zPath;                  /* Name of the file */
-+  unixShm *pShm;                      /* Shared memory segment information */
-+  int szChunk;                        /* Configured by FCNTL_CHUNK_SIZE */
-+  int nFetchOut;                      /* Number of outstanding xFetch refs */
-+  sqlite3_int64 mmapSize;             /* Usable size of mapping at pMapRegion */
-+  sqlite3_int64 mmapSizeActual;       /* Actual size of mapping at pMapRegion */
-+  sqlite3_int64 mmapSizeMax;          /* Configured FCNTL_MMAP_SIZE value */
-+  void *pMapRegion;                   /* Memory mapped region */
-+#ifdef __QNXNTO__
-+  int sectorSize;                     /* Device sector size */
-+  int deviceCharacteristics;          /* Precomputed device characteristics */
-+#endif
-+#if SQLITE_ENABLE_LOCKING_STYLE
-+  int openFlags;                      /* The flags specified at open() */
-+#endif
-+#if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__)
-+  unsigned fsFlags;                   /* cached details from statfs() */
-+#endif
-+#if OS_VXWORKS
-+  struct vxworksFileId *pId;          /* Unique file ID */
-+#endif
-+#ifdef SQLITE_DEBUG
-+  /* The next group of variables are used to track whether or not the
-+  ** transaction counter in bytes 24-27 of database files are updated
-+  ** whenever any part of the database changes.  An assertion fault will
-+  ** occur if a file is updated without also updating the transaction
-+  ** counter.  This test is made to avoid new problems similar to the
-+  ** one described by ticket #3584. 
-   */
--  assert( pFile->pInode->nLock>0 || pFile->pInode->bProcessLock==0 );
--  if( ALWAYS(pFile->pInode) && pFile->pInode->nLock ){
--    /* If there are outstanding locks, do not actually close the file just
--    ** yet because that would clear those locks.  Instead, add the file
--    ** descriptor to pInode->pUnused list.  It will be automatically closed 
--    ** when the last lock is cleared.
--    */
--    setPendingFd(pFile);
--  }
--  releaseInodeInfo(pFile);
--  rc = closeUnixFile(id);
--  unixLeaveMutex();
--  return rc;
--}
--
--/************** End of the posix advisory lock implementation *****************
--******************************************************************************/
-+  unsigned char transCntrChng;   /* True if the transaction counter changed */
-+  unsigned char dbUpdate;        /* True if any part of database file changed */
-+  unsigned char inNormalWrite;   /* True if in a normal write operation */
- 
--/******************************************************************************
--****************************** No-op Locking **********************************
--**
--** Of the various locking implementations available, this is by far the
--** simplest:  locking is ignored.  No attempt is made to lock the database
--** file for reading or writing.
--**
--** This locking mode is appropriate for use on read-only databases
--** (ex: databases that are burned into CD-ROM, for example.)  It can
--** also be used if the application employs some external mechanism to
--** prevent simultaneous access of the same database by two or more
--** database connections.  But there is a serious risk of database
--** corruption if this locking mode is used in situations where multiple
--** database connections are accessing the same database file at the same
--** time and one or more of those connections are writing.
--*/
-+#endif
- 
--static int nolockCheckReservedLock(sqlite3_file *NotUsed, int *pResOut){
--  UNUSED_PARAMETER(NotUsed);
--  *pResOut = 0;
--  return SQLITE_OK;
--}
--static int nolockLock(sqlite3_file *NotUsed, int NotUsed2){
--  UNUSED_PARAMETER2(NotUsed, NotUsed2);
--  return SQLITE_OK;
--}
--static int nolockUnlock(sqlite3_file *NotUsed, int NotUsed2){
--  UNUSED_PARAMETER2(NotUsed, NotUsed2);
--  return SQLITE_OK;
--}
-+#ifdef SQLITE_TEST
-+  /* In test mode, increase the size of this structure a bit so that 
-+  ** it is larger than the struct CrashFile defined in test6.c.
-+  */
-+  char aPadding[32];
-+#endif
-+};
- 
- /*
--** Close the file.
-+** Allowed values for the unixFile.ctrlFlags bitmask:
- */
--static int nolockClose(sqlite3_file *id) {
--  return closeUnixFile(id);
--}
--
--/******************* End of the no-op lock implementation *********************
--******************************************************************************/
-+#define UNIXFILE_EXCL        0x01     /* Connections from one process only */
-+#define UNIXFILE_RDONLY      0x02     /* Connection is read only */
-+#define UNIXFILE_PERSIST_WAL 0x04     /* Persistent WAL mode */
-+#ifndef SQLITE_DISABLE_DIRSYNC
-+# define UNIXFILE_DIRSYNC    0x08     /* Directory sync needed */
-+#else
-+# define UNIXFILE_DIRSYNC    0x00
-+#endif
-+#define UNIXFILE_PSOW        0x10     /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
-+#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 */
- 
--/******************************************************************************
--************************* Begin dot-file Locking ******************************
-+/*
-+** Include code that is common to all os_*.c files
-+*/
-+/************** Include os_common.h in the middle of os_unix.c ***************/
-+/************** Begin file os_common.h ***************************************/
-+/*
-+** 2004 May 22
- **
--** The dotfile locking implementation uses the existence of separate lock
--** files (really a directory) to control access to the database.  This works
--** on just about every filesystem imaginable.  But there are serious downsides:
-+** The author disclaims copyright to this source code.  In place of
-+** a legal notice, here is a blessing:
- **
--**    (1)  There is zero concurrency.  A single reader blocks all other
--**         connections from reading or writing the database.
-+**    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.
- **
--**    (2)  An application crash or power loss can leave stale lock files
--**         sitting around that need to be cleared manually.
-+******************************************************************************
- **
--** Nevertheless, a dotlock is an appropriate locking mode for use if no
--** other locking strategy is available.
-+** This file contains macros and a little bit of code that is common to
-+** all of the platform-specific files (os_*.c) and is #included into those
-+** files.
- **
--** Dotfile locking works by creating a subdirectory in the same directory as
--** the database and with the same name but with a ".lock" extension added.
--** The existence of a lock directory implies an EXCLUSIVE lock.  All other
--** lock types (SHARED, RESERVED, PENDING) are mapped into EXCLUSIVE.
-+** This file should be #included by the os_*.c files only.  It is not a
-+** general purpose header file.
- */
-+#ifndef _OS_COMMON_H_
-+#define _OS_COMMON_H_
- 
- /*
--** The file suffix added to the data base filename in order to create the
--** lock directory.
-+** At least two bugs have slipped in because we changed the MEMORY_DEBUG
-+** macro to SQLITE_DEBUG and some older makefiles have not yet made the
-+** switch.  The following code should catch this problem at compile-time.
- */
--#define DOTLOCK_SUFFIX ".lock"
-+#ifdef MEMORY_DEBUG
-+# 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
- 
- /*
--** 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, set *pResOut
--** 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.
--**
--** In dotfile locking, either a lock exists or it does not.  So in this
--** variation of CheckReservedLock(), *pResOut is set to true if any lock
--** is held on the file and false if the file is unlocked.
-+** Macros for performance tracing.  Normally turned off.  Only works
-+** on i486 hardware.
- */
--static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) {
--  int rc = SQLITE_OK;
--  int reserved = 0;
--  unixFile *pFile = (unixFile*)id;
--
--  SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
--  
--  assert( pFile );
--
--  /* Check if a thread in this process holds such a lock */
--  if( pFile->eFileLock>SHARED_LOCK ){
--    /* Either this connection or some other connection in the same process
--    ** holds a lock on the file.  No need to check further. */
--    reserved = 1;
--  }else{
--    /* The lock is held if and only if the lockfile exists */
--    const char *zLockFile = (const char*)pFile->lockingContext;
--    reserved = osAccess(zLockFile, 0)==0;
--  }
--  OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved));
--  *pResOut = reserved;
--  return rc;
--}
-+#ifdef SQLITE_PERFORMANCE_TRACE
- 
-+/* 
-+** hwtime.h contains inline assembler code for implementing 
-+** high-performance timing routines.
-+*/
-+/************** Include hwtime.h in the middle of os_common.h ****************/
-+/************** Begin file hwtime.h ******************************************/
- /*
--** Lock the file with the lock specified by parameter eFileLock - one
--** of the following:
--**
--**     (1) SHARED_LOCK
--**     (2) RESERVED_LOCK
--**     (3) PENDING_LOCK
--**     (4) EXCLUSIVE_LOCK
-+** 2008 May 27
- **
--** 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:
-+** The author disclaims copyright to this source code.  In place of
-+** a legal notice, here is a blessing:
- **
--**    UNLOCKED -> SHARED
--**    SHARED -> RESERVED
--**    SHARED -> (PENDING) -> EXCLUSIVE
--**    RESERVED -> (PENDING) -> EXCLUSIVE
--**    PENDING -> EXCLUSIVE
-+**    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 routine will only increase a lock.  Use the sqlite3OsUnlock()
--** routine to lower a locking level.
-+******************************************************************************
- **
--** With dotfile locking, we really only support state (4): EXCLUSIVE.
--** But we track the other locking levels internally.
-+** This file contains inline asm code for retrieving "high-performance"
-+** counters for x86 class CPUs.
- */
--static int dotlockLock(sqlite3_file *id, int eFileLock) {
--  unixFile *pFile = (unixFile*)id;
--  char *zLockFile = (char *)pFile->lockingContext;
--  int rc = SQLITE_OK;
-+#ifndef _HWTIME_H_
-+#define _HWTIME_H_
- 
-+/*
-+** The following routine only works on pentium-class (or newer) processors.
-+** It uses the RDTSC opcode to read the cycle count value out of the
-+** processor and returns that value.  This can be used for high-res
-+** profiling.
-+*/
-+#if (defined(__GNUC__) || defined(_MSC_VER)) && \
-+      (defined(i386) || defined(__i386__) || defined(_M_IX86))
- 
--  /* If we have any lock, then the lock file already exists.  All we have
--  ** to do is adjust our internal record of the lock level.
--  */
--  if( pFile->eFileLock > NO_LOCK ){
--    pFile->eFileLock = eFileLock;
--    /* Always update the timestamp on the old file */
--#ifdef HAVE_UTIME
--    utime(zLockFile, NULL);
--#else
--    utimes(zLockFile, NULL);
--#endif
--    return SQLITE_OK;
-+  #if defined(__GNUC__)
-+
-+  __inline__ sqlite_uint64 sqlite3Hwtime(void){
-+     unsigned int lo, hi;
-+     __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
-+     return (sqlite_uint64)hi << 32 | lo;
-   }
--  
--  /* grab an exclusive lock */
--  rc = osMkdir(zLockFile, 0777);
--  if( rc<0 ){
--    /* failed to open/create the lock directory */
--    int tErrno = errno;
--    if( EEXIST == tErrno ){
--      rc = SQLITE_BUSY;
--    } else {
--      rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
--      if( IS_LOCK_ERROR(rc) ){
--        pFile->lastErrno = tErrno;
--      }
--    }
--    return rc;
--  } 
--  
--  /* got it, set the type and return ok */
--  pFile->eFileLock = eFileLock;
--  return rc;
--}
- 
--/*
--** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
--** 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.
--**
--** When the locking level reaches NO_LOCK, delete the lock file.
--*/
--static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
--  unixFile *pFile = (unixFile*)id;
--  char *zLockFile = (char *)pFile->lockingContext;
--  int rc;
-+  #elif defined(_MSC_VER)
- 
--  assert( pFile );
--  OSTRACE(("UNLOCK  %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock,
--           pFile->eFileLock, getpid()));
--  assert( eFileLock<=SHARED_LOCK );
--  
--  /* no-op if possible */
--  if( pFile->eFileLock==eFileLock ){
--    return SQLITE_OK;
-+  __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
-+     __asm {
-+        rdtsc
-+        ret       ; return value at EDX:EAX
-+     }
-   }
- 
--  /* To downgrade to shared, simply update our internal notion of the
--  ** lock state.  No need to mess with the file on disk.
--  */
--  if( eFileLock==SHARED_LOCK ){
--    pFile->eFileLock = SHARED_LOCK;
--    return SQLITE_OK;
-+  #endif
-+
-+#elif (defined(__GNUC__) && defined(__x86_64__))
-+
-+  __inline__ sqlite_uint64 sqlite3Hwtime(void){
-+      unsigned long val;
-+      __asm__ __volatile__ ("rdtsc" : "=A" (val));
-+      return val;
-   }
--  
--  /* To fully unlock the database, delete the lock file */
--  assert( eFileLock==NO_LOCK );
--  rc = osRmdir(zLockFile);
--  if( rc<0 && errno==ENOTDIR ) rc = osUnlink(zLockFile);
--  if( rc<0 ){
--    int tErrno = errno;
--    rc = 0;
--    if( ENOENT != tErrno ){
--      rc = SQLITE_IOERR_UNLOCK;
--    }
--    if( IS_LOCK_ERROR(rc) ){
--      pFile->lastErrno = tErrno;
--    }
--    return rc; 
-+ 
-+#elif (defined(__GNUC__) && defined(__ppc__))
-+
-+  __inline__ sqlite_uint64 sqlite3Hwtime(void){
-+      unsigned long long retval;
-+      unsigned long junk;
-+      __asm__ __volatile__ ("\n\
-+          1:      mftbu   %1\n\
-+                  mftb    %L0\n\
-+                  mftbu   %0\n\
-+                  cmpw    %0,%1\n\
-+                  bne     1b"
-+                  : "=r" (retval), "=r" (junk));
-+      return retval;
-   }
--  pFile->eFileLock = NO_LOCK;
--  return SQLITE_OK;
--}
-+
-+#else
-+
-+  #error Need implementation of sqlite3Hwtime() for your platform.
-+
-+  /*
-+  ** To compile without implementing sqlite3Hwtime() for your platform,
-+  ** you can remove the above #error and use the following
-+  ** stub function.  You will lose timing support for many
-+  ** of the debugging and testing utilities, but it should at
-+  ** least compile and run.
-+  */
-+SQLITE_PRIVATE   sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
-+
-+#endif
-+
-+#endif /* !defined(_HWTIME_H_) */
-+
-+/************** End of hwtime.h **********************************************/
-+/************** Continuing where we left off in os_common.h ******************/
-+
-+static sqlite_uint64 g_start;
-+static sqlite_uint64 g_elapsed;
-+#define TIMER_START       g_start=sqlite3Hwtime()
-+#define TIMER_END         g_elapsed=sqlite3Hwtime()-g_start
-+#define TIMER_ELAPSED     g_elapsed
-+#else
-+#define TIMER_START
-+#define TIMER_END
-+#define TIMER_ELAPSED     ((sqlite_uint64)0)
-+#endif
- 
- /*
--** Close a file.  Make sure the lock has been released before closing.
-+** If we compile with the SQLITE_TEST macro set, then the following block
-+** of code will give us the ability to simulate a disk I/O error.  This
-+** is used for testing the I/O recovery logic.
- */
--static int dotlockClose(sqlite3_file *id) {
--  int rc = SQLITE_OK;
--  if( id ){
--    unixFile *pFile = (unixFile*)id;
--    dotlockUnlock(id, NO_LOCK);
--    sqlite3_free(pFile->lockingContext);
--    rc = closeUnixFile(id);
--  }
--  return rc;
-+#ifdef SQLITE_TEST
-+SQLITE_API int sqlite3_io_error_hit = 0;            /* Total number of I/O Errors */
-+SQLITE_API int sqlite3_io_error_hardhit = 0;        /* Number of non-benign errors */
-+SQLITE_API int sqlite3_io_error_pending = 0;        /* Count down to first I/O error */
-+SQLITE_API int sqlite3_io_error_persist = 0;        /* True if I/O errors persist */
-+SQLITE_API int sqlite3_io_error_benign = 0;         /* True if errors are benign */
-+SQLITE_API int sqlite3_diskfull_pending = 0;
-+SQLITE_API int sqlite3_diskfull = 0;
-+#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X)
-+#define SimulateIOError(CODE)  \
-+  if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \
-+       || sqlite3_io_error_pending-- == 1 )  \
-+              { local_ioerr(); CODE; }
-+static void local_ioerr(){
-+  IOTRACE(("IOERR\n"));
-+  sqlite3_io_error_hit++;
-+  if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++;
- }
--/****************** End of the dot-file lock implementation *******************
--******************************************************************************/
-+#define SimulateDiskfullError(CODE) \
-+   if( sqlite3_diskfull_pending ){ \
-+     if( sqlite3_diskfull_pending == 1 ){ \
-+       local_ioerr(); \
-+       sqlite3_diskfull = 1; \
-+       sqlite3_io_error_hit = 1; \
-+       CODE; \
-+     }else{ \
-+       sqlite3_diskfull_pending--; \
-+     } \
-+   }
-+#else
-+#define SimulateIOErrorBenign(X)
-+#define SimulateIOError(A)
-+#define SimulateDiskfullError(A)
-+#endif
- 
--/******************************************************************************
--************************** Begin flock Locking ********************************
--**
--** Use the flock() system call to do file locking.
--**
--** flock() locking is like dot-file locking in that the various
--** fine-grain locking levels supported by SQLite are collapsed into
--** a single exclusive lock.  In other words, SHARED, RESERVED, and
--** PENDING locks are the same thing as an EXCLUSIVE lock.  SQLite
--** 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.
-+/*
-+** When testing, keep a count of the number of open files.
- */
--#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
-+#ifdef SQLITE_TEST
-+SQLITE_API int sqlite3_open_file_count = 0;
-+#define OpenCounter(X)  sqlite3_open_file_count+=(X)
-+#else
-+#define OpenCounter(X)
-+#endif
-+
-+#endif /* !defined(_OS_COMMON_H_) */
-+
-+/************** End of os_common.h *******************************************/
-+/************** Continuing where we left off in os_unix.c ********************/
-+
-+/*
-+** Define various macros that are missing from some systems.
-+*/
-+#ifndef O_LARGEFILE
-+# define O_LARGEFILE 0
-+#endif
-+#ifdef SQLITE_DISABLE_LFS
-+# undef O_LARGEFILE
-+# define O_LARGEFILE 0
-+#endif
-+#ifndef O_NOFOLLOW
-+# define O_NOFOLLOW 0
-+#endif
-+#ifndef O_BINARY
-+# define O_BINARY 0
-+#endif
- 
- /*
--** Retry flock() calls that fail with EINTR
-+** The threadid macro resolves to the thread-id or to 0.  Used for
-+** testing and debugging only.
- */
--#ifdef EINTR
--static int robust_flock(int fd, int op){
--  int rc;
--  do{ rc = flock(fd,op); }while( rc<0 && errno==EINTR );
--  return rc;
--}
-+#if SQLITE_THREADSAFE
-+#define threadid pthread_self()
- #else
--# define robust_flock(a,b) flock(a,b)
-+#define threadid 0
- #endif
--     
- 
- /*
--** 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, set *pResOut
--** 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.
-+** HAVE_MREMAP defaults to true on Linux and false everywhere else.
- */
--static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
--  int rc = SQLITE_OK;
--  int reserved = 0;
--  unixFile *pFile = (unixFile*)id;
--  
--  SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
--  
--  assert( pFile );
--  
--  /* Check if a thread in this process holds such a lock */
--  if( pFile->eFileLock>SHARED_LOCK ){
--    reserved = 1;
--  }
--  
--  /* Otherwise see if some other process holds it. */
--  if( !reserved ){
--    /* attempt to get the lock */
--    int lrc = robust_flock(pFile->h, LOCK_EX | LOCK_NB);
--    if( !lrc ){
--      /* got the lock, unlock it */
--      lrc = robust_flock(pFile->h, LOCK_UN);
--      if ( lrc ) {
--        int tErrno = errno;
--        /* unlock failed with an error */
--        lrc = SQLITE_IOERR_UNLOCK; 
--        if( IS_LOCK_ERROR(lrc) ){
--          pFile->lastErrno = tErrno;
--          rc = lrc;
--        }
--      }
--    } else {
--      int tErrno = errno;
--      reserved = 1;
--      /* someone else might have it reserved */
--      lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); 
--      if( IS_LOCK_ERROR(lrc) ){
--        pFile->lastErrno = tErrno;
--        rc = lrc;
--      }
--    }
--  }
--  OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved));
--
--#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
--  if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){
--    rc = SQLITE_OK;
--    reserved=1;
--  }
--#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
--  *pResOut = reserved;
--  return rc;
--}
-+#if !defined(HAVE_MREMAP)
-+# if defined(__linux__) && defined(_GNU_SOURCE)
-+#  define HAVE_MREMAP 1
-+# else
-+#  define HAVE_MREMAP 0
-+# endif
-+#endif
- 
- /*
--** Lock the file with the lock specified by parameter eFileLock - 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
--**
--** flock() only really support EXCLUSIVE locks.  We track intermediate
--** lock states in the sqlite3_file structure, but all locks SHARED or
--** above are really EXCLUSIVE locks and exclude all other processes from
--** access the file.
-+** 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.
- **
--** This routine will only increase a lock.  Use the sqlite3OsUnlock()
--** routine to lower a locking level.
-+** The safest way to deal with the problem is to always use this wrapper
-+** which always has the same well-defined interface.
- */
--static int flockLock(sqlite3_file *id, int eFileLock) {
--  int rc = SQLITE_OK;
--  unixFile *pFile = (unixFile*)id;
--
--  assert( pFile );
--
--  /* if we already have a lock, it is exclusive.  
--  ** Just adjust level and punt on outta here. */
--  if (pFile->eFileLock > NO_LOCK) {
--    pFile->eFileLock = eFileLock;
--    return SQLITE_OK;
--  }
--  
--  /* grab an exclusive lock */
--  
--  if (robust_flock(pFile->h, LOCK_EX | LOCK_NB)) {
--    int tErrno = errno;
--    /* didn't get, must be busy */
--    rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
--    if( IS_LOCK_ERROR(rc) ){
--      pFile->lastErrno = tErrno;
--    }
--  } else {
--    /* got it, set the type and return ok */
--    pFile->eFileLock = eFileLock;
--  }
--  OSTRACE(("LOCK    %d %s %s (flock)\n", pFile->h, azFileLock(eFileLock), 
--           rc==SQLITE_OK ? "ok" : "failed"));
--#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
--  if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){
--    rc = SQLITE_BUSY;
--  }
--#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
--  return rc;
-+static int posixOpen(const char *zFile, int flags, int mode){
-+  return open(zFile, flags, mode);
- }
- 
--
- /*
--** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
--** 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.
-+** On some systems, calls to fchown() will trigger a message in a security
-+** log if they come from non-root processes.  So avoid calling fchown() if
-+** we are not running as root.
- */
--static int flockUnlock(sqlite3_file *id, int eFileLock) {
--  unixFile *pFile = (unixFile*)id;
--  
--  assert( pFile );
--  OSTRACE(("UNLOCK  %d %d was %d pid=%d (flock)\n", pFile->h, eFileLock,
--           pFile->eFileLock, getpid()));
--  assert( eFileLock<=SHARED_LOCK );
--  
--  /* no-op if possible */
--  if( pFile->eFileLock==eFileLock ){
--    return SQLITE_OK;
--  }
--  
--  /* shared can just be set because we always have an exclusive */
--  if (eFileLock==SHARED_LOCK) {
--    pFile->eFileLock = eFileLock;
--    return SQLITE_OK;
--  }
--  
--  /* no, really, unlock. */
--  if( robust_flock(pFile->h, LOCK_UN) ){
--#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
--    return SQLITE_OK;
--#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
--    return SQLITE_IOERR_UNLOCK;
--  }else{
--    pFile->eFileLock = NO_LOCK;
--    return SQLITE_OK;
--  }
-+static int posixFchown(int fd, uid_t uid, gid_t gid){
-+  return geteuid() ? 0 : fchown(fd,uid,gid);
- }
- 
-+/* Forward reference */
-+static int openDirectory(const char*, int*);
-+
- /*
--** Close a file.
-+** Many system calls are accessed through pointer-to-functions so that
-+** they may be overridden at runtime to facilitate fault injection during
-+** testing and sandboxing.  The following array holds the names and pointers
-+** to all overrideable system calls.
- */
--static int flockClose(sqlite3_file *id) {
--  int rc = SQLITE_OK;
--  if( id ){
--    flockUnlock(id, NO_LOCK);
--    rc = closeUnixFile(id);
--  }
--  return rc;
--}
-+static struct unix_syscall {
-+  const char *zName;            /* Name of the system call */
-+  sqlite3_syscall_ptr pCurrent; /* Current value of the system call */
-+  sqlite3_syscall_ptr pDefault; /* Default value */
-+} aSyscall[] = {
-+  { "open",         (sqlite3_syscall_ptr)posixOpen,  0  },
-+#define osOpen      ((int(*)(const char*,int,int))aSyscall[0].pCurrent)
- 
--#endif /* SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORK */
-+  { "close",        (sqlite3_syscall_ptr)close,      0  },
-+#define osClose     ((int(*)(int))aSyscall[1].pCurrent)
- 
--/******************* End of the flock lock implementation *********************
--******************************************************************************/
-+  { "access",       (sqlite3_syscall_ptr)access,     0  },
-+#define osAccess    ((int(*)(const char*,int))aSyscall[2].pCurrent)
- 
--/******************************************************************************
--************************ Begin Named Semaphore Locking ************************
--**
--** Named semaphore locking is only supported on VxWorks.
--**
--** Semaphore locking is like dot-lock and flock in that it really only
--** supports EXCLUSIVE locking.  Only a single process can read or write
--** the database file at a time.  This reduces potential concurrency, but
--** makes the lock implementation much easier.
--*/
--#if OS_VXWORKS
-+  { "getcwd",       (sqlite3_syscall_ptr)getcwd,     0  },
-+#define osGetcwd    ((char*(*)(char*,size_t))aSyscall[3].pCurrent)
-+
-+  { "stat",         (sqlite3_syscall_ptr)stat,       0  },
-+#define osStat      ((int(*)(const char*,struct stat*))aSyscall[4].pCurrent)
- 
- /*
--** 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, set *pResOut
--** 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.
-+** The DJGPP compiler environment looks mostly like Unix, but it
-+** lacks the fcntl() system call.  So redefine fcntl() to be something
-+** that always succeeds.  This means that locking does not occur under
-+** DJGPP.  But it is DOS - what did you expect?
- */
--static int semCheckReservedLock(sqlite3_file *id, int *pResOut) {
--  int rc = SQLITE_OK;
--  int reserved = 0;
--  unixFile *pFile = (unixFile*)id;
-+#ifdef __DJGPP__
-+  { "fstat",        0,                 0  },
-+#define osFstat(a,b,c)    0
-+#else     
-+  { "fstat",        (sqlite3_syscall_ptr)fstat,      0  },
-+#define osFstat     ((int(*)(int,struct stat*))aSyscall[5].pCurrent)
-+#endif
- 
--  SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
--  
--  assert( pFile );
-+  { "ftruncate",    (sqlite3_syscall_ptr)ftruncate,  0  },
-+#define osFtruncate ((int(*)(int,off_t))aSyscall[6].pCurrent)
- 
--  /* Check if a thread in this process holds such a lock */
--  if( pFile->eFileLock>SHARED_LOCK ){
--    reserved = 1;
--  }
--  
--  /* Otherwise see if some other process holds it. */
--  if( !reserved ){
--    sem_t *pSem = pFile->pInode->pSem;
--    struct stat statBuf;
-+  { "fcntl",        (sqlite3_syscall_ptr)fcntl,      0  },
-+#define osFcntl     ((int(*)(int,int,...))aSyscall[7].pCurrent)
- 
--    if( sem_trywait(pSem)==-1 ){
--      int tErrno = errno;
--      if( EAGAIN != tErrno ){
--        rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK);
--        pFile->lastErrno = tErrno;
--      } else {
--        /* someone else has the lock when we are in NO_LOCK */
--        reserved = (pFile->eFileLock < SHARED_LOCK);
--      }
--    }else{
--      /* we could have it if we want it */
--      sem_post(pSem);
--    }
--  }
--  OSTRACE(("TEST WR-LOCK %d %d %d (sem)\n", pFile->h, rc, reserved));
-+  { "read",         (sqlite3_syscall_ptr)read,       0  },
-+#define osRead      ((ssize_t(*)(int,void*,size_t))aSyscall[8].pCurrent)
- 
--  *pResOut = reserved;
--  return rc;
--}
-+#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE
-+  { "pread",        (sqlite3_syscall_ptr)pread,      0  },
-+#else
-+  { "pread",        (sqlite3_syscall_ptr)0,          0  },
-+#endif
-+#define osPread     ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[9].pCurrent)
-+
-+#if defined(USE_PREAD64)
-+  { "pread64",      (sqlite3_syscall_ptr)pread64,    0  },
-+#else
-+  { "pread64",      (sqlite3_syscall_ptr)0,          0  },
-+#endif
-+#define osPread64   ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[10].pCurrent)
-+
-+  { "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
-+  { "pwrite",       (sqlite3_syscall_ptr)pwrite,     0  },
-+#else
-+  { "pwrite",       (sqlite3_syscall_ptr)0,          0  },
-+#endif
-+#define osPwrite    ((ssize_t(*)(int,const void*,size_t,off_t))\
-+                    aSyscall[12].pCurrent)
-+
-+#if defined(USE_PREAD64)
-+  { "pwrite64",     (sqlite3_syscall_ptr)pwrite64,   0  },
-+#else
-+  { "pwrite64",     (sqlite3_syscall_ptr)0,          0  },
-+#endif
-+#define osPwrite64  ((ssize_t(*)(int,const void*,size_t,off_t))\
-+                    aSyscall[13].pCurrent)
-+
-+  { "fchmod",       (sqlite3_syscall_ptr)fchmod,     0  },
-+#define osFchmod    ((int(*)(int,mode_t))aSyscall[14].pCurrent)
-+
-+#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
-+  { "fallocate",    (sqlite3_syscall_ptr)posix_fallocate,  0 },
-+#else
-+  { "fallocate",    (sqlite3_syscall_ptr)0,                0 },
-+#endif
-+#define osFallocate ((int(*)(int,off_t,off_t))aSyscall[15].pCurrent)
-+
-+  { "unlink",       (sqlite3_syscall_ptr)unlink,           0 },
-+#define osUnlink    ((int(*)(const char*))aSyscall[16].pCurrent)
-+
-+  { "openDirectory",    (sqlite3_syscall_ptr)openDirectory,      0 },
-+#define osOpenDirectory ((int(*)(const char*,int*))aSyscall[17].pCurrent)
-+
-+  { "mkdir",        (sqlite3_syscall_ptr)mkdir,           0 },
-+#define osMkdir     ((int(*)(const char*,mode_t))aSyscall[18].pCurrent)
-+
-+  { "rmdir",        (sqlite3_syscall_ptr)rmdir,           0 },
-+#define osRmdir     ((int(*)(const char*))aSyscall[19].pCurrent)
-+
-+  { "fchown",       (sqlite3_syscall_ptr)posixFchown,     0 },
-+#define osFchown    ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
-+
-+  { "mmap",       (sqlite3_syscall_ptr)mmap,     0 },
-+#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[21].pCurrent)
-+
-+  { "munmap",       (sqlite3_syscall_ptr)munmap,          0 },
-+#define osMunmap ((void*(*)(void*,size_t))aSyscall[22].pCurrent)
-+
-+#if HAVE_MREMAP
-+  { "mremap",       (sqlite3_syscall_ptr)mremap,          0 },
-+#else
-+  { "mremap",       (sqlite3_syscall_ptr)0,               0 },
-+#endif
-+#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent)
-+
-+}; /* End of the overrideable system calls */
- 
- /*
--** Lock the file with the lock specified by parameter eFileLock - 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
--**
--** Semaphore locks only really support EXCLUSIVE locks.  We track intermediate
--** lock states in the sqlite3_file structure, but all locks SHARED or
--** above are really EXCLUSIVE locks and exclude all other processes from
--** access the file.
--**
--** This routine will only increase a lock.  Use the sqlite3OsUnlock()
--** routine to lower a locking level.
-+** This is the xSetSystemCall() method of sqlite3_vfs for all of the
-+** "unix" 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 semLock(sqlite3_file *id, int eFileLock) {
--  unixFile *pFile = (unixFile*)id;
--  int fd;
--  sem_t *pSem = pFile->pInode->pSem;
--  int rc = SQLITE_OK;
-+static int unixSetSystemCall(
-+  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;
- 
--  /* if we already have a lock, it is exclusive.  
--  ** Just adjust level and punt on outta here. */
--  if (pFile->eFileLock > NO_LOCK) {
--    pFile->eFileLock = eFileLock;
-+  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;
--    goto sem_end_lock;
--  }
--  
--  /* lock semaphore now but bail out when already locked. */
--  if( sem_trywait(pSem)==-1 ){
--    rc = SQLITE_BUSY;
--    goto sem_end_lock;
-+    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;
-+      }
-+    }
-   }
--
--  /* got it, set the type and return ok */
--  pFile->eFileLock = eFileLock;
--
-- sem_end_lock:
-   return rc;
- }
- 
- /*
--** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
--** 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.
-+** 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 int semUnlock(sqlite3_file *id, int eFileLock) {
--  unixFile *pFile = (unixFile*)id;
--  sem_t *pSem = pFile->pInode->pSem;
-+static sqlite3_syscall_ptr unixGetSystemCall(
-+  sqlite3_vfs *pNotUsed,
-+  const char *zName
-+){
-+  unsigned int i;
- 
--  assert( pFile );
--  assert( pSem );
--  OSTRACE(("UNLOCK  %d %d was %d pid=%d (sem)\n", pFile->h, eFileLock,
--           pFile->eFileLock, getpid()));
--  assert( eFileLock<=SHARED_LOCK );
--  
--  /* no-op if possible */
--  if( pFile->eFileLock==eFileLock ){
--    return SQLITE_OK;
--  }
--  
--  /* shared can just be set because we always have an exclusive */
--  if (eFileLock==SHARED_LOCK) {
--    pFile->eFileLock = eFileLock;
--    return SQLITE_OK;
--  }
--  
--  /* no, really unlock. */
--  if ( sem_post(pSem)==-1 ) {
--    int rc, tErrno = errno;
--    rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
--    if( IS_LOCK_ERROR(rc) ){
--      pFile->lastErrno = tErrno;
--    }
--    return rc; 
-+  UNUSED_PARAMETER(pNotUsed);
-+  for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
-+    if( strcmp(zName, aSyscall[i].zName)==0 ) return aSyscall[i].pCurrent;
-   }
--  pFile->eFileLock = NO_LOCK;
--  return SQLITE_OK;
-+  return 0;
- }
- 
- /*
-- ** Close a file.
-- */
--static int semClose(sqlite3_file *id) {
--  if( id ){
--    unixFile *pFile = (unixFile*)id;
--    semUnlock(id, NO_LOCK);
--    assert( pFile );
--    unixEnterMutex();
--    releaseInodeInfo(pFile);
--    unixLeaveMutex();
--    closeUnixFile(id);
-+** 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 *unixNextSystemCall(sqlite3_vfs *p, const char *zName){
-+  int i = -1;
-+
-+  UNUSED_PARAMETER(p);
-+  if( zName ){
-+    for(i=0; i<ArraySize(aSyscall)-1; i++){
-+      if( strcmp(zName, aSyscall[i].zName)==0 ) break;
-+    }
-   }
--  return SQLITE_OK;
-+  for(i++; i<ArraySize(aSyscall); i++){
-+    if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
-+  }
-+  return 0;
- }
- 
--#endif /* OS_VXWORKS */
- /*
--** Named semaphore locking is only available on VxWorks.
--**
--*************** End of the named semaphore lock implementation ****************
--******************************************************************************/
--
--
--/******************************************************************************
--*************************** Begin AFP Locking *********************************
-+** Invoke open().  Do so multiple times, until it either succeeds or
-+** fails for some reason other than EINTR.
- **
--** AFP is the Apple Filing Protocol.  AFP is a network filesystem found
--** on Apple Macintosh computers - both OS9 and OSX.
-+** If the file creation mode "m" is 0 then set it to the default for
-+** SQLite.  The default is SQLITE_DEFAULT_FILE_PERMISSIONS (normally
-+** 0644) as modified by the system umask.  If m is not 0, then
-+** make the file creation mode be exactly m ignoring the umask.
- **
--** Third-party implementations of AFP are available.  But this code here
--** only works on OSX.
-+** The m parameter will be non-zero only when creating -wal, -journal,
-+** and -shm files.  We want those files to have *exactly* the same
-+** permissions as their original database, unadulterated by the umask.
-+** In that way, if a database file is -rw-rw-rw or -rw-rw-r-, and a
-+** transaction crashes and leaves behind hot journals, then any
-+** process that is able to write to the database will also be able to
-+** recover the hot journals.
- */
-+static int robust_open(const char *z, int f, mode_t m){
-+  int fd;
-+  mode_t m2 = m ? m : SQLITE_DEFAULT_FILE_PERMISSIONS;
-+  do{
-+#if defined(O_CLOEXEC)
-+    fd = osOpen(z,f|O_CLOEXEC,m2);
-+#else
-+    fd = osOpen(z,f,m2);
-+#endif
-+  }while( fd<0 && errno==EINTR );
-+  if( fd>=0 ){
-+    if( m!=0 ){
-+      struct stat statbuf;
-+      if( osFstat(fd, &statbuf)==0 
-+       && statbuf.st_size==0
-+       && (statbuf.st_mode&0777)!=m 
-+      ){
-+        osFchmod(fd, m);
-+      }
-+    }
-+#if defined(FD_CLOEXEC) && (!defined(O_CLOEXEC) || O_CLOEXEC==0)
-+    osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
-+#endif
-+  }
-+  return fd;
-+}
- 
--#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
- /*
--** The afpLockingContext structure contains all afp lock specific state
-+** Helper functions to obtain and relinquish the global mutex. The
-+** global mutex is used to protect the unixInodeInfo and
-+** vxworksFileId objects used by this file, all of which may be 
-+** shared by multiple threads.
-+**
-+** Function unixMutexHeld() is used to assert() that the global mutex 
-+** is held when required. This function is only used as part of assert() 
-+** statements. e.g.
-+**
-+**   unixEnterMutex()
-+**     assert( unixMutexHeld() );
-+**   unixEnterLeave()
- */
--typedef struct afpLockingContext afpLockingContext;
--struct afpLockingContext {
--  int reserved;
--  const char *dbPath;             /* Name of the open file */
--};
--
--struct ByteRangeLockPB2
--{
--  unsigned long long offset;        /* offset to first byte to lock */
--  unsigned long long length;        /* nbr of bytes to lock */
--  unsigned long long retRangeStart; /* nbr of 1st byte locked if successful */
--  unsigned char unLockFlag;         /* 1 = unlock, 0 = lock */
--  unsigned char startEndFlag;       /* 1=rel to end of fork, 0=rel to start */
--  int fd;                           /* file desc to assoc this lock with */
--};
-+static void unixEnterMutex(void){
-+  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-+}
-+static void unixLeaveMutex(void){
-+  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-+}
-+#ifdef SQLITE_DEBUG
-+static int unixMutexHeld(void) {
-+  return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-+}
-+#endif
- 
--#define afpfsByteRangeLock2FSCTL        _IOWR('z', 23, struct ByteRangeLockPB2)
- 
-+#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
- /*
--** This is a utility for setting or clearing a bit-range lock on an
--** AFP filesystem.
--** 
--** Return SQLITE_OK on success, SQLITE_BUSY on failure.
-+** Helper function for printing out trace information from debugging
-+** binaries. This returns the string represetation of the supplied
-+** integer lock-type.
- */
--static int afpSetLock(
--  const char *path,              /* Name of the file to be locked or unlocked */
--  unixFile *pFile,               /* Open file descriptor on path */
--  unsigned long long offset,     /* First byte to be locked */
--  unsigned long long length,     /* Number of bytes to lock */
--  int setLockFlag                /* True to set lock.  False to clear lock */
--){
--  struct ByteRangeLockPB2 pb;
--  int err;
--  
--  pb.unLockFlag = setLockFlag ? 0 : 1;
--  pb.startEndFlag = 0;
--  pb.offset = offset;
--  pb.length = length; 
--  pb.fd = pFile->h;
--  
--  OSTRACE(("AFPSETLOCK [%s] for %d%s in range %llx:%llx\n", 
--    (setLockFlag?"ON":"OFF"), pFile->h, (pb.fd==-1?"[testval-1]":""),
--    offset, length));
--  err = fsctl(path, afpfsByteRangeLock2FSCTL, &pb, 0);
--  if ( err==-1 ) {
--    int rc;
--    int tErrno = errno;
--    OSTRACE(("AFPSETLOCK failed to fsctl() '%s' %d %s\n",
--             path, tErrno, strerror(tErrno)));
--#ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS
--    rc = SQLITE_BUSY;
--#else
--    rc = sqliteErrorFromPosixError(tErrno,
--                    setLockFlag ? SQLITE_IOERR_LOCK : SQLITE_IOERR_UNLOCK);
--#endif /* SQLITE_IGNORE_AFP_LOCK_ERRORS */
--    if( IS_LOCK_ERROR(rc) ){
--      pFile->lastErrno = tErrno;
--    }
--    return rc;
--  } else {
--    return SQLITE_OK;
-+static const char *azFileLock(int eFileLock){
-+  switch( eFileLock ){
-+    case NO_LOCK: return "NONE";
-+    case SHARED_LOCK: return "SHARED";
-+    case RESERVED_LOCK: return "RESERVED";
-+    case PENDING_LOCK: return "PENDING";
-+    case EXCLUSIVE_LOCK: return "EXCLUSIVE";
-   }
-+  return "ERROR";
- }
-+#endif
- 
-+#ifdef SQLITE_LOCK_TRACE
- /*
--** 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, set *pResOut
--** 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.
-+** Print out information about all locking operations.
-+**
-+** This routine is used for troubleshooting locks on multithreaded
-+** platforms.  Enable by compiling with the -DSQLITE_LOCK_TRACE
-+** command-line option on the compiler.  This code is normally
-+** turned off.
- */
--static int afpCheckReservedLock(sqlite3_file *id, int *pResOut){
--  int rc = SQLITE_OK;
--  int reserved = 0;
--  unixFile *pFile = (unixFile*)id;
--  afpLockingContext *context;
--  
--  SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
--  
--  assert( pFile );
--  context = (afpLockingContext *) pFile->lockingContext;
--  if( context->reserved ){
--    *pResOut = 1;
--    return SQLITE_OK;
-+static int lockTrace(int fd, int op, struct flock *p){
-+  char *zOpName, *zType;
-+  int s;
-+  int savedErrno;
-+  if( op==F_GETLK ){
-+    zOpName = "GETLK";
-+  }else if( op==F_SETLK ){
-+    zOpName = "SETLK";
-+  }else{
-+    s = osFcntl(fd, op, p);
-+    sqlite3DebugPrintf("fcntl unknown %d %d %d\n", fd, op, s);
-+    return s;
-   }
--  unixEnterMutex(); /* Because pFile->pInode is shared across threads */
--  
--  /* Check if a thread in this process holds such a lock */
--  if( pFile->pInode->eFileLock>SHARED_LOCK ){
--    reserved = 1;
-+  if( p->l_type==F_RDLCK ){
-+    zType = "RDLCK";
-+  }else if( p->l_type==F_WRLCK ){
-+    zType = "WRLCK";
-+  }else if( p->l_type==F_UNLCK ){
-+    zType = "UNLCK";
-+  }else{
-+    assert( 0 );
-   }
--  
--  /* Otherwise see if some other process holds it.
--   */
--  if( !reserved ){
--    /* lock the RESERVED byte */
--    int lrc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1);  
--    if( SQLITE_OK==lrc ){
--      /* if we succeeded in taking the reserved lock, unlock it to restore
--      ** the original state */
--      lrc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1, 0);
--    } else {
--      /* if we failed to get the lock then someone else must have it */
--      reserved = 1;
--    }
--    if( IS_LOCK_ERROR(lrc) ){
--      rc=lrc;
-+  assert( p->l_whence==SEEK_SET );
-+  s = osFcntl(fd, op, p);
-+  savedErrno = errno;
-+  sqlite3DebugPrintf("fcntl %d %d %s %s %d %d %d %d\n",
-+     threadid, fd, zOpName, zType, (int)p->l_start, (int)p->l_len,
-+     (int)p->l_pid, s);
-+  if( s==(-1) && op==F_SETLK && (p->l_type==F_RDLCK || p->l_type==F_WRLCK) ){
-+    struct flock l2;
-+    l2 = *p;
-+    osFcntl(fd, F_GETLK, &l2);
-+    if( l2.l_type==F_RDLCK ){
-+      zType = "RDLCK";
-+    }else if( l2.l_type==F_WRLCK ){
-+      zType = "WRLCK";
-+    }else if( l2.l_type==F_UNLCK ){
-+      zType = "UNLCK";
-+    }else{
-+      assert( 0 );
-     }
-+    sqlite3DebugPrintf("fcntl-failure-reason: %s %d %d %d\n",
-+       zType, (int)l2.l_start, (int)l2.l_len, (int)l2.l_pid);
-   }
--  
--  unixLeaveMutex();
--  OSTRACE(("TEST WR-LOCK %d %d %d (afp)\n", pFile->h, rc, reserved));
--  
--  *pResOut = reserved;
--  return rc;
-+  errno = savedErrno;
-+  return s;
- }
-+#undef osFcntl
-+#define osFcntl lockTrace
-+#endif /* SQLITE_LOCK_TRACE */
- 
- /*
--** Lock the file with the lock specified by parameter eFileLock - 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.  Use the sqlite3OsUnlock()
--** routine to lower a locking level.
-+** Retry ftruncate() calls that fail due to EINTR
- */
--static int afpLock(sqlite3_file *id, int eFileLock){
--  int rc = SQLITE_OK;
--  unixFile *pFile = (unixFile*)id;
--  unixInodeInfo *pInode = pFile->pInode;
--  afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
--  
--  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()));
-+static int robust_ftruncate(int h, sqlite3_int64 sz){
-+  int rc;
-+  do{ rc = osFtruncate(h,sz); }while( rc<0 && errno==EINTR );
-+  return rc;
-+}
- 
--  /* 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
--  ** unixEnterMutex() hasn't been called yet.
-+/*
-+** This routine translates a standard POSIX errno code into something
-+** useful to the clients of the sqlite3 functions.  Specifically, it is
-+** intended to translate a variety of "try again" errors into SQLITE_BUSY
-+** and a variety of "please close the file descriptor NOW" errors into 
-+** SQLITE_IOERR
-+** 
-+** Errors during initialization of locks, or file system support for locks,
-+** should handle ENOLCK, ENOTSUP, EOPNOTSUPP separately.
-+*/
-+static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) {
-+  switch (posixError) {
-+#if 0
-+  /* At one point this code was not commented out. In theory, this branch
-+  ** should never be hit, as this function should only be called after
-+  ** a locking-related function (i.e. fcntl()) has returned non-zero with
-+  ** the value of errno as the first argument. Since a system call has failed,
-+  ** errno should be non-zero.
-+  **
-+  ** Despite this, if errno really is zero, we still don't want to return
-+  ** SQLITE_OK. The system call failed, and *some* SQLite error should be
-+  ** propagated back to the caller. Commenting this branch out means errno==0
-+  ** will be handled by the "default:" case below.
-   */
--  if( pFile->eFileLock>=eFileLock ){
--    OSTRACE(("LOCK    %d %s ok (already held) (afp)\n", pFile->h,
--           azFileLock(eFileLock)));
-+  case 0: 
-     return SQLITE_OK;
--  }
--
--  /* Make sure the locking sequence is correct
--  **  (1) We never move from unlocked to anything higher than shared lock.
--  **  (2) SQLite never explicitly requests a pendig lock.
--  **  (3) A shared lock is always held when a reserve lock is requested.
--  */
--  assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK );
--  assert( eFileLock!=PENDING_LOCK );
--  assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK );
--  
--  /* This mutex is needed because pFile->pInode is shared across threads
--  */
--  unixEnterMutex();
--  pInode = pFile->pInode;
-+#endif
- 
--  /* If some thread using this PID has a lock via a different unixFile*
--  ** handle that precludes the requested lock, return BUSY.
--  */
--  if( (pFile->eFileLock!=pInode->eFileLock && 
--       (pInode->eFileLock>=PENDING_LOCK || eFileLock>SHARED_LOCK))
--     ){
--    rc = SQLITE_BUSY;
--    goto afp_end_lock;
--  }
--  
--  /* If a SHARED lock is requested, and some thread using this PID already
--  ** has a SHARED or RESERVED lock, then increment reference counts and
--  ** return SQLITE_OK.
--  */
--  if( eFileLock==SHARED_LOCK && 
--     (pInode->eFileLock==SHARED_LOCK || pInode->eFileLock==RESERVED_LOCK) ){
--    assert( eFileLock==SHARED_LOCK );
--    assert( pFile->eFileLock==0 );
--    assert( pInode->nShared>0 );
--    pFile->eFileLock = SHARED_LOCK;
--    pInode->nShared++;
--    pInode->nLock++;
--    goto afp_end_lock;
--  }
-+  case EAGAIN:
-+  case ETIMEDOUT:
-+  case EBUSY:
-+  case EINTR:
-+  case ENOLCK:  
-+    /* random NFS retry error, unless during file system support 
-+     * introspection, in which it actually means what it says */
-+    return SQLITE_BUSY;
-     
--  /* A PENDING lock is needed before acquiring a SHARED lock and before
--  ** acquiring an EXCLUSIVE lock.  For the SHARED lock, the PENDING will
--  ** be released.
--  */
--  if( eFileLock==SHARED_LOCK 
--      || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLock<PENDING_LOCK)
--  ){
--    int failed;
--    failed = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 1);
--    if (failed) {
--      rc = failed;
--      goto afp_end_lock;
-+  case EACCES: 
-+    /* EACCES is like EAGAIN during locking operations, but not any other time*/
-+    if( (sqliteIOErr == SQLITE_IOERR_LOCK) || 
-+        (sqliteIOErr == SQLITE_IOERR_UNLOCK) || 
-+        (sqliteIOErr == SQLITE_IOERR_RDLOCK) ||
-+        (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ){
-+      return SQLITE_BUSY;
-     }
--  }
--  
--  /* If control gets to this point, then actually go ahead and make
--  ** operating system calls for the specified lock.
--  */
--  if( eFileLock==SHARED_LOCK ){
--    int lrc1, lrc2, lrc1Errno = 0;
--    long lk, mask;
-+    /* else fall through */
-+  case EPERM: 
-+    return SQLITE_PERM;
-     
--    assert( pInode->nShared==0 );
--    assert( pInode->eFileLock==0 );
--        
--    mask = (sizeof(long)==8) ? LARGEST_INT64 : 0x7fffffff;
--    /* Now get the read-lock SHARED_LOCK */
--    /* note that the quality of the randomness doesn't matter that much */
--    lk = random(); 
--    pInode->sharedByte = (lk & mask)%(SHARED_SIZE - 1);
--    lrc1 = afpSetLock(context->dbPath, pFile, 
--          SHARED_FIRST+pInode->sharedByte, 1, 1);
--    if( IS_LOCK_ERROR(lrc1) ){
--      lrc1Errno = pFile->lastErrno;
--    }
--    /* Drop the temporary PENDING lock */
--    lrc2 = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0);
-+  /* EDEADLK is only possible if a call to fcntl(F_SETLKW) is made. And
-+  ** this module never makes such a call. And the code in SQLite itself 
-+  ** asserts that SQLITE_IOERR_BLOCKED is never returned. For these reasons
-+  ** this case is also commented out. If the system does set errno to EDEADLK,
-+  ** the default SQLITE_IOERR_XXX code will be returned. */
-+#if 0
-+  case EDEADLK:
-+    return SQLITE_IOERR_BLOCKED;
-+#endif
-     
--    if( IS_LOCK_ERROR(lrc1) ) {
--      pFile->lastErrno = lrc1Errno;
--      rc = lrc1;
--      goto afp_end_lock;
--    } else if( IS_LOCK_ERROR(lrc2) ){
--      rc = lrc2;
--      goto afp_end_lock;
--    } else if( lrc1 != SQLITE_OK ) {
--      rc = lrc1;
--    } else {
--      pFile->eFileLock = SHARED_LOCK;
--      pInode->nLock++;
--      pInode->nShared = 1;
--    }
--  }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){
--    /* We are trying for an exclusive lock but another thread in this
--     ** same process is still holding a shared lock. */
--    rc = SQLITE_BUSY;
--  }else{
--    /* The request was for a RESERVED or EXCLUSIVE lock.  It is
--    ** assumed that there is a SHARED or greater lock on the file
--    ** already.
--    */
--    int failed = 0;
--    assert( 0!=pFile->eFileLock );
--    if (eFileLock >= RESERVED_LOCK && pFile->eFileLock < RESERVED_LOCK) {
--        /* Acquire a RESERVED lock */
--        failed = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1);
--      if( !failed ){
--        context->reserved = 1;
-+#if EOPNOTSUPP!=ENOTSUP
-+  case EOPNOTSUPP: 
-+    /* something went terribly awry, unless during file system support 
-+     * introspection, in which it actually means what it says */
-+#endif
-+#ifdef ENOTSUP
-+  case ENOTSUP: 
-+    /* invalid fd, unless during file system support introspection, in which 
-+     * it actually means what it says */
-+#endif
-+  case EIO:
-+  case EBADF:
-+  case EINVAL:
-+  case ENOTCONN:
-+  case ENODEV:
-+  case ENXIO:
-+  case ENOENT:
-+#ifdef ESTALE                     /* ESTALE is not defined on Interix systems */
-+  case ESTALE:
-+#endif
-+  case ENOSYS:
-+    /* these should force the client to close the file and reconnect */
-+    
-+  default: 
-+    return sqliteIOErr;
-+  }
-+}
-+
-+
-+/******************************************************************************
-+****************** Begin Unique File ID Utility Used By VxWorks ***************
-+**
-+** On most versions of unix, we can get a unique ID for a file by concatenating
-+** the device number and the inode number.  But this does not work on VxWorks.
-+** On VxWorks, a unique file id must be based on the canonical filename.
-+**
-+** A pointer to an instance of the following structure can be used as a
-+** unique file ID in VxWorks.  Each instance of this structure contains
-+** a copy of the canonical filename.  There is also a reference count.  
-+** The structure is reclaimed when the number of pointers to it drops to
-+** zero.
-+**
-+** There are never very many files open at one time and lookups are not
-+** a performance-critical path, so it is sufficient to put these
-+** structures on a linked list.
-+*/
-+struct vxworksFileId {
-+  struct vxworksFileId *pNext;  /* Next in a list of them all */
-+  int nRef;                     /* Number of references to this one */
-+  int nName;                    /* Length of the zCanonicalName[] string */
-+  char *zCanonicalName;         /* Canonical filename */
-+};
-+
-+#if OS_VXWORKS
-+/* 
-+** All unique filenames are held on a linked list headed by this
-+** variable:
-+*/
-+static struct vxworksFileId *vxworksFileList = 0;
-+
-+/*
-+** Simplify a filename into its canonical form
-+** by making the following changes:
-+**
-+**  * removing any trailing and duplicate /
-+**  * convert /./ into just /
-+**  * convert /A/../ where A is any simple name into just /
-+**
-+** Changes are made in-place.  Return the new name length.
-+**
-+** The original filename is in z[0..n-1].  Return the number of
-+** characters in the simplified name.
-+*/
-+static int vxworksSimplifyName(char *z, int n){
-+  int i, j;
-+  while( n>1 && z[n-1]=='/' ){ n--; }
-+  for(i=j=0; i<n; i++){
-+    if( z[i]=='/' ){
-+      if( z[i+1]=='/' ) continue;
-+      if( z[i+1]=='.' && i+2<n && z[i+2]=='/' ){
-+        i += 1;
-+        continue;
-       }
--    }
--    if (!failed && eFileLock == EXCLUSIVE_LOCK) {
--      /* Acquire an EXCLUSIVE lock */
--        
--      /* Remove the shared lock before trying the range.  we'll need to 
--      ** reestablish the shared lock if we can't get the  afpUnlock
--      */
--      if( !(failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST +
--                         pInode->sharedByte, 1, 0)) ){
--        int failed2 = SQLITE_OK;
--        /* now attemmpt to get the exclusive lock range */
--        failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST, 
--                               SHARED_SIZE, 1);
--        if( failed && (failed2 = afpSetLock(context->dbPath, pFile, 
--                       SHARED_FIRST + pInode->sharedByte, 1, 1)) ){
--          /* Can't reestablish the shared lock.  Sqlite can't deal, this is
--          ** a critical I/O error
--          */
--          rc = ((failed & SQLITE_IOERR) == SQLITE_IOERR) ? failed2 : 
--               SQLITE_IOERR_LOCK;
--          goto afp_end_lock;
--        } 
--      }else{
--        rc = failed; 
-+      if( z[i+1]=='.' && i+3<n && z[i+2]=='.' && z[i+3]=='/' ){
-+        while( j>0 && z[j-1]!='/' ){ j--; }
-+        if( j>0 ){ j--; }
-+        i += 2;
-+        continue;
-       }
-     }
--    if( failed ){
--      rc = failed;
--    }
--  }
--  
--  if( rc==SQLITE_OK ){
--    pFile->eFileLock = eFileLock;
--    pInode->eFileLock = eFileLock;
--  }else if( eFileLock==EXCLUSIVE_LOCK ){
--    pFile->eFileLock = PENDING_LOCK;
--    pInode->eFileLock = PENDING_LOCK;
-+    z[j++] = z[i];
-   }
--  
--afp_end_lock:
--  unixLeaveMutex();
--  OSTRACE(("LOCK    %d %s %s (afp)\n", pFile->h, azFileLock(eFileLock), 
--         rc==SQLITE_OK ? "ok" : "failed"));
--  return rc;
-+  z[j] = 0;
-+  return j;
- }
- 
- /*
--** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
--** must be either NO_LOCK or SHARED_LOCK.
-+** Find a unique file ID for the given absolute pathname.  Return
-+** a pointer to the vxworksFileId object.  This pointer is the unique
-+** file ID.
- **
--** If the locking level of the file descriptor is already at or below
--** the requested locking level, this routine is a no-op.
-+** The nRef field of the vxworksFileId object is incremented before
-+** the object is returned.  A new vxworksFileId object is created
-+** and added to the global list if necessary.
-+**
-+** If a memory allocation error occurs, return NULL.
- */
--static int afpUnlock(sqlite3_file *id, int eFileLock) {
--  int rc = SQLITE_OK;
--  unixFile *pFile = (unixFile*)id;
--  unixInodeInfo *pInode;
--  afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
--  int skipShared = 0;
--#ifdef SQLITE_TEST
--  int h = pFile->h;
--#endif
-+static struct vxworksFileId *vxworksFindFileId(const char *zAbsoluteName){
-+  struct vxworksFileId *pNew;         /* search key and new file ID */
-+  struct vxworksFileId *pCandidate;   /* For looping over existing file IDs */
-+  int n;                              /* Length of zAbsoluteName string */
- 
--  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()));
-+  assert( zAbsoluteName[0]=='/' );
-+  n = (int)strlen(zAbsoluteName);
-+  pNew = sqlite3_malloc( sizeof(*pNew) + (n+1) );
-+  if( pNew==0 ) return 0;
-+  pNew->zCanonicalName = (char*)&pNew[1];
-+  memcpy(pNew->zCanonicalName, zAbsoluteName, n+1);
-+  n = vxworksSimplifyName(pNew->zCanonicalName, n);
- 
--  assert( eFileLock<=SHARED_LOCK );
--  if( pFile->eFileLock<=eFileLock ){
--    return SQLITE_OK;
--  }
-+  /* Search for an existing entry that matching the canonical name.
-+  ** If found, increment the reference count and return a pointer to
-+  ** the existing file ID.
-+  */
-   unixEnterMutex();
--  pInode = pFile->pInode;
--  assert( pInode->nShared!=0 );
--  if( pFile->eFileLock>SHARED_LOCK ){
--    assert( pInode->eFileLock==pFile->eFileLock );
--    SimulateIOErrorBenign(1);
--    SimulateIOError( h=(-1) )
--    SimulateIOErrorBenign(0);
--    
--#ifdef SQLITE_DEBUG
--    /* When reducing a lock such that other processes can start
--    ** reading the database file again, make sure that the
--    ** transaction counter was updated if any part of the database
--    ** file changed.  If the transaction counter is not updated,
--    ** other connections to the same file might not realize that
--    ** the file has changed and hence might not know to flush their
--    ** cache.  The use of a stale cache can lead to database corruption.
--    */
--    assert( pFile->inNormalWrite==0
--           || pFile->dbUpdate==0
--           || pFile->transCntrChng==1 );
--    pFile->inNormalWrite = 0;
--#endif
--    
--    if( pFile->eFileLock==EXCLUSIVE_LOCK ){
--      rc = afpSetLock(context->dbPath, pFile, SHARED_FIRST, SHARED_SIZE, 0);
--      if( rc==SQLITE_OK && (eFileLock==SHARED_LOCK || pInode->nShared>1) ){
--        /* only re-establish the shared lock if necessary */
--        int sharedLockByte = SHARED_FIRST+pInode->sharedByte;
--        rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 1);
--      } else {
--        skipShared = 1;
--      }
--    }
--    if( rc==SQLITE_OK && pFile->eFileLock>=PENDING_LOCK ){
--      rc = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0);
--    } 
--    if( rc==SQLITE_OK && pFile->eFileLock>=RESERVED_LOCK && context->reserved ){
--      rc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1, 0);
--      if( !rc ){ 
--        context->reserved = 0; 
--      }
--    }
--    if( rc==SQLITE_OK && (eFileLock==SHARED_LOCK || pInode->nShared>1)){
--      pInode->eFileLock = SHARED_LOCK;
-+  for(pCandidate=vxworksFileList; pCandidate; pCandidate=pCandidate->pNext){
-+    if( pCandidate->nName==n 
-+     && memcmp(pCandidate->zCanonicalName, pNew->zCanonicalName, n)==0
-+    ){
-+       sqlite3_free(pNew);
-+       pCandidate->nRef++;
-+       unixLeaveMutex();
-+       return pCandidate;
-     }
-   }
--  if( rc==SQLITE_OK && eFileLock==NO_LOCK ){
- 
--    /* Decrement the shared lock counter.  Release the lock using an
--    ** OS call only when all threads in this same process have released
--    ** the lock.
--    */
--    unsigned long long sharedLockByte = SHARED_FIRST+pInode->sharedByte;
--    pInode->nShared--;
--    if( pInode->nShared==0 ){
--      SimulateIOErrorBenign(1);
--      SimulateIOError( h=(-1) )
--      SimulateIOErrorBenign(0);
--      if( !skipShared ){
--        rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 0);
--      }
--      if( !rc ){
--        pInode->eFileLock = NO_LOCK;
--        pFile->eFileLock = NO_LOCK;
--      }
--    }
--    if( rc==SQLITE_OK ){
--      pInode->nLock--;
--      assert( pInode->nLock>=0 );
--      if( pInode->nLock==0 ){
--        closePendingFds(pFile);
--      }
--    }
--  }
--  
-+  /* No match was found.  We will make a new file ID */
-+  pNew->nRef = 1;
-+  pNew->nName = n;
-+  pNew->pNext = vxworksFileList;
-+  vxworksFileList = pNew;
-   unixLeaveMutex();
--  if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock;
--  return rc;
-+  return pNew;
- }
- 
- /*
--** Close a file & cleanup AFP specific locking context 
-+** Decrement the reference count on a vxworksFileId object.  Free
-+** the object when the reference count reaches zero.
- */
--static int afpClose(sqlite3_file *id) {
--  int rc = SQLITE_OK;
--  if( id ){
--    unixFile *pFile = (unixFile*)id;
--    afpUnlock(id, NO_LOCK);
--    unixEnterMutex();
--    if( pFile->pInode && pFile->pInode->nLock ){
--      /* If there are outstanding locks, do not actually close the file just
--      ** yet because that would clear those locks.  Instead, add the file
--      ** descriptor to pInode->aPending.  It will be automatically closed when
--      ** the last lock is cleared.
--      */
--      setPendingFd(pFile);
--    }
--    releaseInodeInfo(pFile);
--    sqlite3_free(pFile->lockingContext);
--    rc = closeUnixFile(id);
--    unixLeaveMutex();
-+static void vxworksReleaseFileId(struct vxworksFileId *pId){
-+  unixEnterMutex();
-+  assert( pId->nRef>0 );
-+  pId->nRef--;
-+  if( pId->nRef==0 ){
-+    struct vxworksFileId **pp;
-+    for(pp=&vxworksFileList; *pp && *pp!=pId; pp = &((*pp)->pNext)){}
-+    assert( *pp==pId );
-+    *pp = pId->pNext;
-+    sqlite3_free(pId);
-   }
--  return rc;
-+  unixLeaveMutex();
- }
--
--#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
--/*
--** The code above is the AFP lock implementation.  The code is specific
--** to MacOSX and does not work on other unix platforms.  No alternative
--** is available.  If you don't compile for a mac, then the "unix-afp"
--** VFS is not available.
--**
--********************* End of the AFP lock implementation **********************
-+#endif /* OS_VXWORKS */
-+/*************** End of Unique File ID Utility Used By VxWorks ****************
- ******************************************************************************/
- 
--/******************************************************************************
--*************************** Begin NFS Locking ********************************/
--
--#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
--/*
-- ** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
-- ** 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.
-- */
--static int nfsUnlock(sqlite3_file *id, int eFileLock){
--  return posixUnlock(id, eFileLock, 1);
--}
--
--#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
--/*
--** The code above is the NFS lock implementation.  The code is specific
--** to MacOSX and does not work on other unix platforms.  No alternative
--** is available.  
--**
--********************* End of the NFS lock implementation **********************
--******************************************************************************/
- 
- /******************************************************************************
--**************** Non-locking sqlite3_file methods *****************************
-+*************************** Posix Advisory Locking ****************************
- **
--** The next division contains implementations for all methods of the 
--** sqlite3_file object other than the locking methods.  The locking
--** methods were defined in divisions above (one locking method per
--** division).  Those methods that are common to all locking modes
--** are gather together into this division.
-+** POSIX advisory locks are broken by design.  ANSI STD 1003.1 (1996)
-+** section 6.5.2.2 lines 483 through 490 specify that when a process
-+** sets or clears a lock, that operation overrides any prior locks set
-+** by the same process.  It does not explicitly say so, but this implies
-+** that it overrides locks set by the same process using a different
-+** file descriptor.  Consider this test case:
-+**
-+**       int fd1 = open("./file1", O_RDWR|O_CREAT, 0644);
-+**       int fd2 = open("./file2", O_RDWR|O_CREAT, 0644);
-+**
-+** Suppose ./file1 and ./file2 are really the same file (because
-+** one is a hard or symbolic link to the other) then if you set
-+** an exclusive lock on fd1, then try to get an exclusive lock
-+** on fd2, it works.  I would have expected the second lock to
-+** fail since there was already a lock on the file due to fd1.
-+** But not so.  Since both locks came from the same process, the
-+** second overrides the first, even though they were on different
-+** file descriptors opened on different file names.
-+**
-+** This means that we cannot use POSIX locks to synchronize file access
-+** among competing threads of the same process.  POSIX locks will work fine
-+** to synchronize access for threads in separate processes, but not
-+** threads within the same process.
-+**
-+** To work around the problem, SQLite has to manage file locks internally
-+** on its own.  Whenever a new database is opened, we have to find the
-+** specific inode of the database file (the inode is determined by the
-+** st_dev and st_ino fields of the stat structure that fstat() fills in)
-+** and check for locks already existing on that inode.  When locks are
-+** created or removed, we have to look at our own internal record of the
-+** locks to see if another thread has previously set a lock on that same
-+** inode.
-+**
-+** (Aside: The use of inode numbers as unique IDs does not work on VxWorks.
-+** For VxWorks, we have to use the alternative unique ID system based on
-+** canonical filename and implemented in the previous division.)
-+**
-+** The sqlite3_file structure for POSIX is no longer just an integer file
-+** descriptor.  It is now a structure that holds the integer file
-+** descriptor and a pointer to a structure that describes the internal
-+** locks on the corresponding inode.  There is one locking structure
-+** per inode, so if the same inode is opened twice, both unixFile structures
-+** point to the same locking structure.  The locking structure keeps
-+** a reference count (so we will know when to delete it) and a "cnt"
-+** field that tells us its internal lock status.  cnt==0 means the
-+** file is unlocked.  cnt==-1 means the file has an exclusive lock.
-+** cnt>0 means there are cnt shared locks on the file.
-+**
-+** Any attempt to lock or unlock a file first checks the locking
-+** structure.  The fcntl() system call is only invoked to set a 
-+** POSIX lock if the internal lock structure transitions between
-+** a locked and an unlocked state.
-+**
-+** But wait:  there are yet more problems with POSIX advisory locks.
-+**
-+** If you close a file descriptor that points to a file that has locks,
-+** all locks on that file that are owned by the current process are
-+** released.  To work around this problem, each unixInodeInfo object
-+** maintains a count of the number of pending locks on tha inode.
-+** When an attempt is made to close an unixFile, if there are
-+** other unixFile open on the same inode that are holding locks, the call
-+** to close() the file descriptor is deferred until all of the locks clear.
-+** The unixInodeInfo structure keeps a list of file descriptors that need to
-+** be closed and that list is walked (and cleared) when the last lock
-+** clears.
-+**
-+** Yet another problem:  LinuxThreads do not play well with posix locks.
-+**
-+** Many older versions of linux use the LinuxThreads library which is
-+** not posix compliant.  Under LinuxThreads, a lock created by thread
-+** A cannot be modified or overridden by a different thread B.
-+** Only thread A can modify the lock.  Locking behavior is correct
-+** if the appliation uses the newer Native Posix Thread Library (NPTL)
-+** on linux - with NPTL a lock created by thread A can override locks
-+** in thread B.  But there is no way to know at compile-time which
-+** threading library is being used.  So there is no way to know at
-+** compile-time whether or not thread A can override locks on thread B.
-+** One has to do a run-time check to discover the behavior of the
-+** current process.
-+**
-+** SQLite used to support LinuxThreads.  But support for LinuxThreads
-+** was dropped beginning with version 3.7.0.  SQLite will still work with
-+** LinuxThreads provided that (1) there is no more than one connection 
-+** per database file in the same process and (2) database connections
-+** do not move across threads.
- */
- 
- /*
--** Seek to the offset passed as the second argument, then read cnt 
--** bytes into pBuf. Return the number of bytes actually read.
--**
--** 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.
--** See tickets #2741 and #2681.
--**
--** To avoid stomping the errno value on a failed read the lastErrno value
--** is set before returning.
-+** An instance of the following structure serves as the key used
-+** to locate a particular unixInodeInfo object.
- */
--static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
--  int got;
--  int prior = 0;
--#if (!defined(USE_PREAD) && !defined(USE_PREAD64))
--  i64 newOffset;
--#endif
--  TIMER_START;
--  assert( cnt==(cnt&0x1ffff) );
--  cnt &= 0x1ffff;
--  do{
--#if defined(USE_PREAD)
--    got = osPread(id->h, pBuf, cnt, offset);
--    SimulateIOError( got = -1 );
--#elif defined(USE_PREAD64)
--    got = osPread64(id->h, pBuf, cnt, offset);
--    SimulateIOError( got = -1 );
-+struct unixFileId {
-+  dev_t dev;                  /* Device number */
-+#if OS_VXWORKS
-+  struct vxworksFileId *pId;  /* Unique file ID for vxworks. */
- #else
--    newOffset = lseek(id->h, offset, SEEK_SET);
--    SimulateIOError( newOffset-- );
--    if( newOffset!=offset ){
--      if( newOffset == -1 ){
--        ((unixFile*)id)->lastErrno = errno;
--      }else{
--        ((unixFile*)id)->lastErrno = 0;
--      }
--      return -1;
--    }
--    got = osRead(id->h, pBuf, cnt);
-+  ino_t ino;                  /* Inode number */
- #endif
--    if( got==cnt ) break;
--    if( got<0 ){
--      if( errno==EINTR ){ got = 1; continue; }
--      prior = 0;
--      ((unixFile*)id)->lastErrno = errno;
--      break;
--    }else if( got>0 ){
--      cnt -= got;
--      offset += got;
--      prior += got;
--      pBuf = (void*)(got + (char*)pBuf);
--    }
--  }while( got>0 );
--  TIMER_END;
--  OSTRACE(("READ    %-3d %5d %7lld %llu\n",
--            id->h, got+prior, offset-prior, TIMER_ELAPSED));
--  return got+prior;
--}
-+};
- 
- /*
--** Read data from a file into a buffer.  Return SQLITE_OK if all
--** bytes were read successfully and SQLITE_IOERR if anything goes
--** wrong.
-+** An instance of the following structure is allocated for each open
-+** inode.  Or, on LinuxThreads, there is one of these structures for
-+** each inode opened by each thread.
-+**
-+** A single inode can have multiple file descriptors, so each unixFile
-+** structure contains a pointer to an instance of this object and this
-+** object keeps a count of the number of unixFile pointing to it.
- */
--static int unixRead(
--  sqlite3_file *id, 
--  void *pBuf, 
--  int amt,
--  sqlite3_int64 offset
--){
--  unixFile *pFile = (unixFile *)id;
--  int got;
--  assert( id );
--  assert( offset>=0 );
--  assert( amt>0 );
--
--  /* If this is a database file (not a journal, master-journal or temp
--  ** file), the bytes in the locking range should never be read or written. */
--#if 0
--  assert( pFile->pUnused==0
--       || offset>=PENDING_BYTE+512
--       || offset+amt<=PENDING_BYTE 
--  );
-+struct unixInodeInfo {
-+  struct unixFileId fileId;       /* The lookup key */
-+  int nShared;                    /* Number of SHARED locks held */
-+  unsigned char eFileLock;        /* One of SHARED_LOCK, RESERVED_LOCK etc. */
-+  unsigned char bProcessLock;     /* An exclusive process lock is held */
-+  int nRef;                       /* Number of pointers to this structure */
-+  unixShmNode *pShmNode;          /* Shared memory associated with this inode */
-+  int nLock;                      /* Number of outstanding file locks */
-+  UnixUnusedFd *pUnused;          /* Unused file descriptors to close */
-+  unixInodeInfo *pNext;           /* List of all unixInodeInfo objects */
-+  unixInodeInfo *pPrev;           /*    .... doubly linked */
-+#if SQLITE_ENABLE_LOCKING_STYLE
-+  unsigned long long sharedByte;  /* for AFP simulated shared lock */
- #endif
--
--#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);
--      return SQLITE_OK;
--    }else{
--      int nCopy = pFile->mmapSize - offset;
--      memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy);
--      pBuf = &((u8 *)pBuf)[nCopy];
--      amt -= nCopy;
--      offset += nCopy;
--    }
--  }
-+#if OS_VXWORKS
-+  sem_t *pSem;                    /* Named POSIX semaphore */
-+  char aSemName[MAX_PATHNAME+2];  /* Name of that semaphore */
- #endif
-+};
- 
--  got = seekAndRead(pFile, offset, pBuf, amt);
--  if( got==amt ){
--    return SQLITE_OK;
--  }else if( got<0 ){
--    /* lastErrno set by seekAndRead */
--    return SQLITE_IOERR_READ;
--  }else{
--    pFile->lastErrno = 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;
--  }
--}
-+/*
-+** A lists of all unixInodeInfo objects.
-+*/
-+static unixInodeInfo *inodeList = 0;
- 
- /*
--** Attempt to seek the file-descriptor passed as the first argument to
--** absolute offset iOff, then attempt to write nBuf bytes of data from
--** pBuf to it. If an error occurs, return -1 and set *piErrno. Otherwise, 
--** return the actual number of bytes written (which may be less than
--** nBuf).
-+**
-+** This function - unixLogError_x(), is only ever called via the macro
-+** unixLogError().
-+**
-+** It is invoked after an error occurs in an OS function and errno has been
-+** set. It logs a message using sqlite3_log() containing the current value of
-+** errno and, if possible, the human-readable equivalent from strerror() or
-+** strerror_r().
-+**
-+** 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 (e.g. "unlink", "open") and the associated file-system path,
-+** if any.
- */
--static int seekAndWriteFd(
--  int fd,                         /* File descriptor to write to */
--  i64 iOff,                       /* File offset to begin writing at */
--  const void *pBuf,               /* Copy data from this buffer to the file */
--  int nBuf,                       /* Size of buffer pBuf in bytes */
--  int *piErrno                    /* OUT: Error number if error occurs */
-+#define unixLogError(a,b,c)     unixLogErrorAtLine(a,b,c,__LINE__)
-+static int unixLogErrorAtLine(
-+  int errcode,                    /* SQLite error code */
-+  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 */
- ){
--  int rc = 0;                     /* Value returned by system call */
-+  char *zErr;                     /* Message from strerror() or equivalent */
-+  int iErrno = errno;             /* Saved syscall error number */
- 
--  assert( nBuf==(nBuf&0x1ffff) );
--  nBuf &= 0x1ffff;
--  TIMER_START;
-+  /* If this is not a threadsafe build (SQLITE_THREADSAFE==0), then use
-+  ** the strerror() function to obtain the human-readable error message
-+  ** equivalent to errno. Otherwise, use strerror_r().
-+  */ 
-+#if SQLITE_THREADSAFE && defined(HAVE_STRERROR_R)
-+  char aErr[80];
-+  memset(aErr, 0, sizeof(aErr));
-+  zErr = aErr;
- 
--#if defined(USE_PREAD)
--  do{ rc = 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);
--#else
--  do{
--    i64 iSeek = lseek(fd, iOff, SEEK_SET);
--    SimulateIOError( iSeek-- );
-+  /* If STRERROR_R_CHAR_P (set by autoconf scripts) or __USE_GNU is defined,
-+  ** assume that the system provides the GNU version of strerror_r() that
-+  ** returns a pointer to a buffer containing the error message. That pointer 
-+  ** may point to aErr[], or it may point to some static storage somewhere. 
-+  ** Otherwise, assume that the system provides the POSIX version of 
-+  ** strerror_r(), which always writes an error message into aErr[].
-+  **
-+  ** If the code incorrectly assumes that it is the POSIX version that is
-+  ** available, the error message will often be an empty string. Not a
-+  ** huge problem. Incorrectly concluding that the GNU version is available 
-+  ** could lead to a segfault though.
-+  */
-+#if defined(STRERROR_R_CHAR_P) || defined(__USE_GNU)
-+  zErr = 
-+# endif
-+  strerror_r(iErrno, aErr, sizeof(aErr)-1);
- 
--    if( iSeek!=iOff ){
--      if( piErrno ) *piErrno = (iSeek==-1 ? errno : 0);
--      return -1;
--    }
--    rc = osWrite(fd, pBuf, nBuf);
--  }while( rc<0 && errno==EINTR );
-+#elif SQLITE_THREADSAFE
-+  /* This is a threadsafe build, but strerror_r() is not available. */
-+  zErr = "";
-+#else
-+  /* Non-threadsafe build, use strerror(). */
-+  zErr = strerror(iErrno);
- #endif
- 
--  TIMER_END;
--  OSTRACE(("WRITE   %-3d %5d %7lld %llu\n", fd, rc, iOff, TIMER_ELAPSED));
-+  if( zPath==0 ) zPath = "";
-+  sqlite3_log(errcode,
-+      "os_unix.c:%d: (%d) %s(%s) - %s",
-+      iLine, iErrno, zFunc, zPath, zErr
-+  );
- 
--  if( rc<0 && piErrno ) *piErrno = errno;
--  return rc;
-+  return errcode;
- }
- 
--
- /*
--** Seek to the offset in id->offset then read cnt bytes into pBuf.
--** Return the number of bytes actually read.  Update the offset.
-+** Close a file descriptor.
- **
--** To avoid stomping the errno value on a failed write the lastErrno value
--** is set before returning.
-+** We assume that close() almost always works, since it is only in a
-+** very sick application or on a very sick platform that it might fail.
-+** If it does fail, simply leak the file descriptor, but do log the
-+** error.
-+**
-+** Note that it is not safe to retry close() after EINTR since the
-+** file descriptor might have already been reused by another thread.
-+** So we don't even try to recover from an EINTR.  Just log the error
-+** and move on.
- */
--static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){
--  return seekAndWriteFd(id->h, offset, pBuf, cnt, &id->lastErrno);
-+static void robust_close(unixFile *pFile, int h, int lineno){
-+  if( osClose(h) ){
-+    unixLogErrorAtLine(SQLITE_IOERR_CLOSE, "close",
-+                       pFile ? pFile->zPath : 0, lineno);
-+  }
- }
- 
-+/*
-+** Close all file descriptors accumuated in the unixInodeInfo->pUnused list.
-+*/ 
-+static void closePendingFds(unixFile *pFile){
-+  unixInodeInfo *pInode = pFile->pInode;
-+  UnixUnusedFd *p;
-+  UnixUnusedFd *pNext;
-+  for(p=pInode->pUnused; p; p=pNext){
-+    pNext = p->pNext;
-+    robust_close(pFile, p->fd, __LINE__);
-+    sqlite3_free(p);
-+  }
-+  pInode->pUnused = 0;
-+}
- 
- /*
--** Write data from a buffer into a file.  Return SQLITE_OK on success
--** or some other error code on failure.
-+** Release a unixInodeInfo structure previously allocated by findInodeInfo().
-+**
-+** The mutex entered using the unixEnterMutex() function must be held
-+** when this function is called.
- */
--static int unixWrite(
--  sqlite3_file *id, 
--  const void *pBuf, 
--  int amt,
--  sqlite3_int64 offset 
-+static void releaseInodeInfo(unixFile *pFile){
-+  unixInodeInfo *pInode = pFile->pInode;
-+  assert( unixMutexHeld() );
-+  if( ALWAYS(pInode) ){
-+    pInode->nRef--;
-+    if( pInode->nRef==0 ){
-+      assert( pInode->pShmNode==0 );
-+      closePendingFds(pFile);
-+      if( pInode->pPrev ){
-+        assert( pInode->pPrev->pNext==pInode );
-+        pInode->pPrev->pNext = pInode->pNext;
-+      }else{
-+        assert( inodeList==pInode );
-+        inodeList = pInode->pNext;
-+      }
-+      if( pInode->pNext ){
-+        assert( pInode->pNext->pPrev==pInode );
-+        pInode->pNext->pPrev = pInode->pPrev;
-+      }
-+      sqlite3_free(pInode);
-+    }
-+  }
-+}
-+
-+/*
-+** Given a file descriptor, locate the unixInodeInfo object that
-+** describes that file descriptor.  Create a new one if necessary.  The
-+** return value might be uninitialized if an error occurs.
-+**
-+** The mutex entered using the unixEnterMutex() function must be held
-+** when this function is called.
-+**
-+** Return an appropriate error code.
-+*/
-+static int findInodeInfo(
-+  unixFile *pFile,               /* Unix file with file desc used in the key */
-+  unixInodeInfo **ppInode        /* Return the unixInodeInfo object here */
- ){
--  unixFile *pFile = (unixFile*)id;
--  int wrote = 0;
--  assert( id );
--  assert( amt>0 );
-+  int rc;                        /* System call return code */
-+  int fd;                        /* The file descriptor for pFile */
-+  struct unixFileId fileId;      /* Lookup key for the unixInodeInfo */
-+  struct stat statbuf;           /* Low-level file information */
-+  unixInodeInfo *pInode = 0;     /* Candidate unixInodeInfo object */
- 
--  /* If this is a database file (not a journal, master-journal or temp
--  ** file), the bytes in the locking range should never be read or written. */
--#if 0
--  assert( pFile->pUnused==0
--       || offset>=PENDING_BYTE+512
--       || offset+amt<=PENDING_BYTE 
--  );
--#endif
-+  assert( unixMutexHeld() );
- 
--#ifdef SQLITE_DEBUG
--  /* If we are doing a normal write to a database file (as opposed to
--  ** doing a hot-journal rollback or a write to some file other than a
--  ** normal database file) then record the fact that the database
--  ** has changed.  If the transaction counter is modified, record that
--  ** fact too.
-+  /* Get low-level information about the file that we can used to
-+  ** create a unique name for the file.
-   */
--  if( pFile->inNormalWrite ){
--    pFile->dbUpdate = 1;  /* The database has been modified */
--    if( offset<=24 && offset+amt>=27 ){
--      int rc;
--      char oldCntr[4];
--      SimulateIOErrorBenign(1);
--      rc = seekAndRead(pFile, 24, oldCntr, 4);
--      SimulateIOErrorBenign(0);
--      if( rc!=4 || memcmp(oldCntr, &((char*)pBuf)[24-offset], 4)!=0 ){
--        pFile->transCntrChng = 1;  /* The transaction counter has changed */
--      }
--    }
--  }
-+  fd = pFile->h;
-+  rc = osFstat(fd, &statbuf);
-+  if( rc!=0 ){
-+    pFile->lastErrno = errno;
-+#ifdef EOVERFLOW
-+    if( pFile->lastErrno==EOVERFLOW ) return SQLITE_NOLFS;
- #endif
-+    return SQLITE_IOERR;
-+  }
- 
--#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);
--      return SQLITE_OK;
--    }else{
--      int nCopy = pFile->mmapSize - offset;
--      memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy);
--      pBuf = &((u8 *)pBuf)[nCopy];
--      amt -= nCopy;
--      offset += nCopy;
-+#ifdef __APPLE__
-+  /* On OS X on an msdos filesystem, the inode number is reported
-+  ** incorrectly for zero-size files.  See ticket #3260.  To work
-+  ** around this problem (we consider it a bug in OS X, not SQLite)
-+  ** we always increase the file size to 1 by writing a single byte
-+  ** prior to accessing the inode number.  The one byte written is
-+  ** an ASCII 'S' character which also happens to be the first byte
-+  ** in the header of every SQLite database.  In this way, if there
-+  ** is a race condition such that another thread has already populated
-+  ** the first page of the database, no damage is done.
-+  */
-+  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;
-+      return SQLITE_IOERR;
-+    }
-+    rc = osFstat(fd, &statbuf);
-+    if( rc!=0 ){
-+      pFile->lastErrno = errno;
-+      return SQLITE_IOERR;
-     }
-   }
- #endif
- 
--  while( amt>0 && (wrote = seekAndWrite(pFile, offset, pBuf, amt))>0 ){
--    amt -= wrote;
--    offset += wrote;
--    pBuf = &((char*)pBuf)[wrote];
-+  memset(&fileId, 0, sizeof(fileId));
-+  fileId.dev = statbuf.st_dev;
-+#if OS_VXWORKS
-+  fileId.pId = pFile->pId;
-+#else
-+  fileId.ino = statbuf.st_ino;
-+#endif
-+  pInode = inodeList;
-+  while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){
-+    pInode = pInode->pNext;
-   }
--  SimulateIOError(( wrote=(-1), amt=1 ));
--  SimulateDiskfullError(( wrote=0, amt=1 ));
--
--  if( amt>0 ){
--    if( wrote<0 && pFile->lastErrno!=ENOSPC ){
--      /* lastErrno set by seekAndWrite */
--      return SQLITE_IOERR_WRITE;
--    }else{
--      pFile->lastErrno = 0; /* not a system error */
--      return SQLITE_FULL;
-+  if( pInode==0 ){
-+    pInode = sqlite3_malloc( sizeof(*pInode) );
-+    if( pInode==0 ){
-+      return SQLITE_NOMEM;
-     }
-+    memset(pInode, 0, sizeof(*pInode));
-+    memcpy(&pInode->fileId, &fileId, sizeof(fileId));
-+    pInode->nRef = 1;
-+    pInode->pNext = inodeList;
-+    pInode->pPrev = 0;
-+    if( inodeList ) inodeList->pPrev = pInode;
-+    inodeList = pInode;
-+  }else{
-+    pInode->nRef++;
-   }
--
-+  *ppInode = pInode;
-   return SQLITE_OK;
- }
- 
--#ifdef SQLITE_TEST
--/*
--** Count the number of fullsyncs and normal syncs.  This is used to test
--** that syncs and fullsyncs are occurring at the right times.
--*/
--SQLITE_API int sqlite3_sync_count = 0;
--SQLITE_API int sqlite3_fullsync_count = 0;
--#endif
--
--/*
--** 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
--*/
--#if !defined(fdatasync)
--# define fdatasync fsync
--#endif
- 
- /*
--** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not
--** the F_FULLFSYNC macro is defined.  F_FULLFSYNC is currently
--** only available on Mac OS X.  But that could change.
-+** Check a unixFile that is a database.  Verify the following:
-+**
-+** (1) There is exactly one hard link on the file
-+** (2) The file is not a symbolic link
-+** (3) The file has not been renamed or unlinked
-+**
-+** Issue sqlite3_log(SQLITE_WARNING,...) messages if anything is not right.
- */
--#ifdef F_FULLFSYNC
--# define HAVE_FULLFSYNC 1
--#else
--# define HAVE_FULLFSYNC 0
--#endif
-+static void verifyDbFile(unixFile *pFile){
-+  struct stat buf;
-+  int rc;
-+  if( pFile->ctrlFlags & UNIXFILE_WARNED ){
-+    /* One or more of the following warnings have already been issued.  Do not
-+    ** repeat them so as not to clutter the error log */
-+    return;
-+  }
-+  rc = osFstat(pFile->h, &buf);
-+  if( rc!=0 ){
-+    sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath);
-+    pFile->ctrlFlags |= UNIXFILE_WARNED;
-+    return;
-+  }
-+  if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){
-+    sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath);
-+    pFile->ctrlFlags |= UNIXFILE_WARNED;
-+    return;
-+  }
-+  if( buf.st_nlink>1 ){
-+    sqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath);
-+    pFile->ctrlFlags |= UNIXFILE_WARNED;
-+    return;
-+  }
-+  if( pFile->pInode!=0
-+   && ((rc = osStat(pFile->zPath, &buf))!=0
-+       || buf.st_ino!=pFile->pInode->fileId.ino)
-+  ){
-+    sqlite3_log(SQLITE_WARNING, "file renamed while open: %s", pFile->zPath);
-+    pFile->ctrlFlags |= UNIXFILE_WARNED;
-+    return;
-+  }
-+}
- 
- 
- /*
--** The fsync() system call does not work as advertised on many
--** unix systems.  The following procedure is an attempt to make
--** it work better.
--**
--** The SQLITE_NO_SYNC macro disables all fsync()s.  This is useful
--** for testing when we want to run through the test suite quickly.
--** You are strongly advised *not* to deploy with SQLITE_NO_SYNC
--** enabled, however, since with SQLITE_NO_SYNC enabled, an OS crash
--** or power failure will likely corrupt the database file.
--**
--** SQLite sets the dataOnly flag if the size of the file is unchanged.
--** The idea behind dataOnly is that it should only write the file content
--** to disk, not the inode.  We only set dataOnly if the file size is 
--** unchanged since the file size is part of the inode.  However, 
--** Ted Ts'o tells us that fdatasync() will also write the inode if the
--** file size has changed.  The only real difference between fdatasync()
--** and fsync(), Ted tells us, is that fdatasync() will not flush the
--** inode if the mtime or owner or other inode attributes have changed.
--** We only care about the file size, not the other file attributes, so
--** as far as SQLite is concerned, an fdatasync() is always adequate.
--** So, we always use fdatasync() if it is available, regardless of
--** the value of the dataOnly flag.
-+** 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, set *pResOut
-+** 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 full_fsync(int fd, int fullSync, int dataOnly){
--  int rc;
-+static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
-+  int rc = SQLITE_OK;
-+  int reserved = 0;
-+  unixFile *pFile = (unixFile*)id;
- 
--  /* The following "ifdef/elif/else/" block has the same structure as
--  ** the one below. It is replicated here solely to avoid cluttering 
--  ** up the real code with the UNUSED_PARAMETER() macros.
--  */
--#ifdef SQLITE_NO_SYNC
--  UNUSED_PARAMETER(fd);
--  UNUSED_PARAMETER(fullSync);
--  UNUSED_PARAMETER(dataOnly);
--#elif HAVE_FULLFSYNC
--  UNUSED_PARAMETER(dataOnly);
--#else
--  UNUSED_PARAMETER(fullSync);
--  UNUSED_PARAMETER(dataOnly);
--#endif
-+  SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
- 
--  /* Record the number of times that we do a normal fsync() and 
--  ** FULLSYNC.  This is used during testing to verify that this procedure
--  ** gets called with the correct arguments.
--  */
--#ifdef SQLITE_TEST
--  if( fullSync ) sqlite3_fullsync_count++;
--  sqlite3_sync_count++;
--#endif
-+  assert( pFile );
-+  unixEnterMutex(); /* Because pFile->pInode is shared across threads */
- 
--  /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
--  ** no-op
--  */
--#ifdef SQLITE_NO_SYNC
--  rc = SQLITE_OK;
--#elif HAVE_FULLFSYNC
--  if( fullSync ){
--    rc = osFcntl(fd, F_FULLFSYNC, 0);
--  }else{
--    rc = 1;
-+  /* Check if a thread in this process holds such a lock */
-+  if( pFile->pInode->eFileLock>SHARED_LOCK ){
-+    reserved = 1;
-   }
--  /* If the FULLFSYNC failed, fall back to attempting an fsync().
--  ** It shouldn't be possible for fullfsync to fail on the local 
--  ** file system (on OSX), so failure indicates that FULLFSYNC
--  ** isn't supported for this file system. So, attempt an fsync 
--  ** and (for now) ignore the overhead of a superfluous fcntl call.  
--  ** It'd be better to detect fullfsync support once and avoid 
--  ** the fcntl call every time sync is called.
--  */
--  if( rc ) rc = fsync(fd);
- 
--#elif defined(__APPLE__)
--  /* fdatasync() on HFS+ doesn't yet flush the file size if it changed correctly
--  ** so currently we default to the macro that redefines fdatasync to fsync
-+  /* Otherwise see if some other process holds it.
-   */
--  rc = fsync(fd);
--#else 
--  rc = fdatasync(fd);
--#if OS_VXWORKS
--  if( rc==-1 && errno==ENOTSUP ){
--    rc = fsync(fd);
-+#ifndef __DJGPP__
-+  if( !reserved && !pFile->pInode->bProcessLock ){
-+    struct flock lock;
-+    lock.l_whence = SEEK_SET;
-+    lock.l_start = RESERVED_BYTE;
-+    lock.l_len = 1;
-+    lock.l_type = F_WRLCK;
-+    if( osFcntl(pFile->h, F_GETLK, &lock) ){
-+      rc = SQLITE_IOERR_CHECKRESERVEDLOCK;
-+      pFile->lastErrno = errno;
-+    } else if( lock.l_type!=F_UNLCK ){
-+      reserved = 1;
-+    }
-   }
--#endif /* OS_VXWORKS */
--#endif /* ifdef SQLITE_NO_SYNC elif HAVE_FULLFSYNC */
-+#endif
-+  
-+  unixLeaveMutex();
-+  OSTRACE(("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved));
- 
--  if( OS_VXWORKS && rc!= -1 ){
--    rc = 0;
--  }
-+  *pResOut = reserved;
-   return rc;
- }
- 
- /*
--** Open a file descriptor to the directory containing file zFilename.
--** If successful, *pFd is set to the opened file descriptor and
--** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM
--** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined
--** value.
--**
--** The directory file descriptor is used for only one thing - to
--** fsync() a directory to make sure file creation and deletion events
--** are flushed to disk.  Such fsyncs are not needed on newer
--** journaling filesystems, but are required on older filesystems.
-+** Attempt to set a system-lock on the file pFile.  The lock is 
-+** described by pLock.
- **
--** This routine can be overridden using the xSetSysCall interface.
--** The ability to override this routine was added in support of the
--** chromium sandbox.  Opening a directory is a security risk (we are
--** told) so making it overrideable allows the chromium sandbox to
--** replace this routine with a harmless no-op.  To make this routine
--** a no-op, replace it with a stub that returns SQLITE_OK but leaves
--** *pFd set to a negative number.
-+** If the pFile was opened read/write from unix-excl, then the only lock
-+** ever obtained is an exclusive lock, and it is obtained exactly once
-+** the first time any lock is attempted.  All subsequent system locking
-+** operations become no-ops.  Locking operations still happen internally,
-+** in order to coordinate access between separate database connections
-+** within this process, but all of that is handled in memory and the
-+** operating system does not participate.
- **
--** If SQLITE_OK is returned, the caller is responsible for closing
--** the file descriptor *pFd using close().
--*/
--static int openDirectory(const char *zFilename, int *pFd){
--  int ii;
--  int fd = -1;
--  char zDirname[MAX_PATHNAME+1];
--
--  sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename);
--  for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--);
--  if( ii>0 ){
--    zDirname[ii] = '\0';
--    fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
--    if( fd>=0 ){
--      OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
-+** This function is a pass-through to fcntl(F_SETLK) if pFile is using
-+** any VFS other than "unix-excl" or if pFile is opened on "unix-excl"
-+** and is read-only.
-+**
-+** Zero is returned if the call completes successfully, or -1 if a call
-+** to fcntl() fails. In this case, errno is set appropriately (by fcntl()).
-+*/
-+static int unixFileLock(unixFile *pFile, struct flock *pLock){
-+  int rc;
-+  unixInodeInfo *pInode = pFile->pInode;
-+  assert( unixMutexHeld() );
-+  assert( pInode!=0 );
-+  if( ((pFile->ctrlFlags & UNIXFILE_EXCL)!=0 || pInode->bProcessLock)
-+   && ((pFile->ctrlFlags & UNIXFILE_RDONLY)==0)
-+  ){
-+    if( pInode->bProcessLock==0 ){
-+      struct flock lock;
-+      assert( pInode->nLock==0 );
-+      lock.l_whence = SEEK_SET;
-+      lock.l_start = SHARED_FIRST;
-+      lock.l_len = SHARED_SIZE;
-+      lock.l_type = F_WRLCK;
-+      rc = osFcntl(pFile->h, F_SETLK, &lock);
-+      if( rc<0 ) return rc;
-+      pInode->bProcessLock = 1;
-+      pInode->nLock++;
-+    }else{
-+      rc = 0;
-     }
-+  }else{
-+    rc = osFcntl(pFile->h, F_SETLK, pLock);
-   }
--  *pFd = fd;
--  return (fd>=0?SQLITE_OK:unixLogError(SQLITE_CANTOPEN_BKPT, "open", zDirname));
-+  return rc;
- }
- 
- /*
--** Make sure all writes to a particular file are committed to disk.
-+** Lock the file with the lock specified by parameter eFileLock - one
-+** of the following:
- **
--** If dataOnly==0 then both the file itself and its metadata (file
--** size, access time, etc) are synced.  If dataOnly!=0 then only the
--** file data is synced.
-+**     (1) SHARED_LOCK
-+**     (2) RESERVED_LOCK
-+**     (3) PENDING_LOCK
-+**     (4) EXCLUSIVE_LOCK
- **
--** Under Unix, also make sure that the directory entry for the file
--** has been created by fsync-ing the directory that contains the file.
--** If we do not do this and we encounter a power failure, the directory
--** entry for the journal might not exist after we reboot.  The next
--** SQLite to access the file will not know that the journal exists (because
--** the directory entry for the journal was never created) and the transaction
--** will not roll back - possibly leading to database corruption.
-+** 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.  Use the sqlite3OsUnlock()
-+** routine to lower a locking level.
- */
--static int unixSync(sqlite3_file *id, int flags){
--  int rc;
-+static int unixLock(sqlite3_file *id, int eFileLock){
-+  /* The following describes the implementation of the various locks and
-+  ** lock transitions in terms of the POSIX advisory shared and exclusive
-+  ** lock primitives (called read-locks and write-locks below, to avoid
-+  ** confusion with SQLite lock names). The algorithms are complicated
-+  ** slightly in order to be compatible with windows systems simultaneously
-+  ** accessing the same database file, in case that is ever required.
-+  **
-+  ** Symbols defined in os.h indentify the 'pending byte' and the 'reserved
-+  ** byte', each single bytes at well known offsets, and the 'shared byte
-+  ** range', a range of 510 bytes at a well known offset.
-+  **
-+  ** To obtain a SHARED lock, a read-lock is obtained on the 'pending
-+  ** byte'.  If this is successful, a random byte from the 'shared byte
-+  ** range' is read-locked and the lock on the 'pending byte' released.
-+  **
-+  ** A process may only obtain a RESERVED lock after it has a SHARED lock.
-+  ** A RESERVED lock is implemented by grabbing a write-lock on the
-+  ** 'reserved byte'. 
-+  **
-+  ** A process may only obtain a PENDING lock after it has obtained a
-+  ** SHARED lock. A PENDING lock is implemented by obtaining a write-lock
-+  ** on the 'pending byte'. This ensures that no new SHARED locks can be
-+  ** obtained, but existing SHARED locks are allowed to persist. A process
-+  ** does not have to obtain a RESERVED lock on the way to a PENDING lock.
-+  ** This property is used by the algorithm for rolling back a journal file
-+  ** after a crash.
-+  **
-+  ** An EXCLUSIVE lock, obtained after a PENDING lock is held, is
-+  ** implemented by obtaining a write-lock on the entire 'shared byte
-+  ** range'. Since all other locks require a read-lock on one of the bytes
-+  ** within this range, this ensures that no other locks are held on the
-+  ** database. 
-+  **
-+  ** The reason a single byte cannot be used instead of the 'shared byte
-+  ** range' is that some versions of windows do not support read-locks. By
-+  ** locking a random byte from a range, concurrent SHARED locks may exist
-+  ** even if the locking primitive used is always a write-lock.
-+  */
-+  int rc = SQLITE_OK;
-   unixFile *pFile = (unixFile*)id;
-+  unixInodeInfo *pInode;
-+  struct flock lock;
-+  int tErrno = 0;
- 
--  int isDataOnly = (flags&SQLITE_SYNC_DATAONLY);
--  int isFullsync = (flags&0x0F)==SQLITE_SYNC_FULL;
-+  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()));
- 
--  /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */
--  assert((flags&0x0F)==SQLITE_SYNC_NORMAL
--      || (flags&0x0F)==SQLITE_SYNC_FULL
--  );
-+  /* 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
-+  ** unixEnterMutex() hasn't been called yet.
-+  */
-+  if( pFile->eFileLock>=eFileLock ){
-+    OSTRACE(("LOCK    %d %s ok (already held) (unix)\n", pFile->h,
-+            azFileLock(eFileLock)));
-+    return SQLITE_OK;
-+  }
- 
--  /* Unix cannot, but some systems may return SQLITE_FULL from here. This
--  ** line is to test that doing so does not cause any problems.
-+  /* Make sure the locking sequence is correct.
-+  **  (1) We never move from unlocked to anything higher than shared lock.
-+  **  (2) SQLite never explicitly requests a pendig lock.
-+  **  (3) A shared lock is always held when a reserve lock is requested.
-   */
--  SimulateDiskfullError( return SQLITE_FULL );
-+  assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK );
-+  assert( eFileLock!=PENDING_LOCK );
-+  assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK );
- 
--  assert( pFile );
--  OSTRACE(("SYNC    %-3d\n", pFile->h));
--  rc = full_fsync(pFile->h, isFullsync, isDataOnly);
--  SimulateIOError( rc=1 );
--  if( rc ){
--    pFile->lastErrno = errno;
--    return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath);
-+  /* This mutex is needed because pFile->pInode is shared across threads
-+  */
-+  unixEnterMutex();
-+  pInode = pFile->pInode;
-+
-+  /* If some thread using this PID has a lock via a different unixFile*
-+  ** handle that precludes the requested lock, return BUSY.
-+  */
-+  if( (pFile->eFileLock!=pInode->eFileLock && 
-+          (pInode->eFileLock>=PENDING_LOCK || eFileLock>SHARED_LOCK))
-+  ){
-+    rc = SQLITE_BUSY;
-+    goto end_lock;
-   }
- 
--  /* Also fsync the directory containing the file if the DIRSYNC flag
--  ** is set.  This is a one-time occurrence.  Many systems (examples: AIX)
--  ** are unable to fsync a directory, so ignore errors on the fsync.
-+  /* If a SHARED lock is requested, and some thread using this PID already
-+  ** has a SHARED or RESERVED lock, then increment reference counts and
-+  ** return SQLITE_OK.
-   */
--  if( pFile->ctrlFlags & UNIXFILE_DIRSYNC ){
--    int dirfd;
--    OSTRACE(("DIRSYNC %s (have_fullfsync=%d fullsync=%d)\n", pFile->zPath,
--            HAVE_FULLFSYNC, isFullsync));
--    rc = osOpenDirectory(pFile->zPath, &dirfd);
--    if( rc==SQLITE_OK && dirfd>=0 ){
--      full_fsync(dirfd, 0, 0);
--      robust_close(pFile, dirfd, __LINE__);
--    }else if( rc==SQLITE_CANTOPEN ){
--      rc = SQLITE_OK;
--    }
--    pFile->ctrlFlags &= ~UNIXFILE_DIRSYNC;
-+  if( eFileLock==SHARED_LOCK && 
-+      (pInode->eFileLock==SHARED_LOCK || pInode->eFileLock==RESERVED_LOCK) ){
-+    assert( eFileLock==SHARED_LOCK );
-+    assert( pFile->eFileLock==0 );
-+    assert( pInode->nShared>0 );
-+    pFile->eFileLock = SHARED_LOCK;
-+    pInode->nShared++;
-+    pInode->nLock++;
-+    goto end_lock;
-   }
--  return rc;
--}
- 
--/*
--** Truncate an open file to a specified size
--*/
--static int unixTruncate(sqlite3_file *id, i64 nByte){
--  unixFile *pFile = (unixFile *)id;
--  int rc;
--  assert( pFile );
--  SimulateIOError( return SQLITE_IOERR_TRUNCATE );
- 
--  /* 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).
-+  /* A PENDING lock is needed before acquiring a SHARED lock and before
-+  ** acquiring an EXCLUSIVE lock.  For the SHARED lock, the PENDING will
-+  ** be released.
-   */
--  if( pFile->szChunk>0 ){
--    nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
-+  lock.l_len = 1L;
-+  lock.l_whence = SEEK_SET;
-+  if( eFileLock==SHARED_LOCK 
-+      || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLock<PENDING_LOCK)
-+  ){
-+    lock.l_type = (eFileLock==SHARED_LOCK?F_RDLCK:F_WRLCK);
-+    lock.l_start = PENDING_BYTE;
-+    if( unixFileLock(pFile, &lock) ){
-+      tErrno = errno;
-+      rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
-+      if( rc!=SQLITE_BUSY ){
-+        pFile->lastErrno = tErrno;
-+      }
-+      goto end_lock;
-+    }
-   }
- 
--  rc = robust_ftruncate(pFile->h, (off_t)nByte);
--  if( rc ){
--    pFile->lastErrno = errno;
--    return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
--  }else{
--#ifdef SQLITE_DEBUG
--    /* If we are doing a normal write to a database file (as opposed to
--    ** doing a hot-journal rollback or a write to some file other than a
--    ** normal database file) and we truncate the file to zero length,
--    ** that effectively updates the change counter.  This might happen
--    ** when restoring a database using the backup API from a zero-length
--    ** source.
--    */
--    if( pFile->inNormalWrite && nByte==0 ){
--      pFile->transCntrChng = 1;
-+
-+  /* If control gets to this point, then actually go ahead and make
-+  ** operating system calls for the specified lock.
-+  */
-+  if( eFileLock==SHARED_LOCK ){
-+    assert( pInode->nShared==0 );
-+    assert( pInode->eFileLock==0 );
-+    assert( rc==SQLITE_OK );
-+
-+    /* Now get the read-lock */
-+    lock.l_start = SHARED_FIRST;
-+    lock.l_len = SHARED_SIZE;
-+    if( unixFileLock(pFile, &lock) ){
-+      tErrno = errno;
-+      rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
-     }
--#endif
- 
--    /* If the file was just 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.  
-+    /* Drop the temporary PENDING lock */
-+    lock.l_start = PENDING_BYTE;
-+    lock.l_len = 1L;
-+    lock.l_type = F_UNLCK;
-+    if( unixFileLock(pFile, &lock) && rc==SQLITE_OK ){
-+      /* This could happen with a network mount */
-+      tErrno = errno;
-+      rc = SQLITE_IOERR_UNLOCK; 
-+    }
-+
-+    if( rc ){
-+      if( rc!=SQLITE_BUSY ){
-+        pFile->lastErrno = tErrno;
-+      }
-+      goto end_lock;
-+    }else{
-+      pFile->eFileLock = SHARED_LOCK;
-+      pInode->nLock++;
-+      pInode->nShared = 1;
-+    }
-+  }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){
-+    /* We are trying for an exclusive lock but another thread in this
-+    ** same process is still holding a shared lock. */
-+    rc = SQLITE_BUSY;
-+  }else{
-+    /* The request was for a RESERVED or EXCLUSIVE lock.  It is
-+    ** assumed that there is a SHARED or greater lock on the file
-+    ** already.
-     */
--    if( nByte<pFile->mmapSize ){
--      pFile->mmapSize = nByte;
-+    assert( 0!=pFile->eFileLock );
-+    lock.l_type = F_WRLCK;
-+
-+    assert( eFileLock==RESERVED_LOCK || eFileLock==EXCLUSIVE_LOCK );
-+    if( eFileLock==RESERVED_LOCK ){
-+      lock.l_start = RESERVED_BYTE;
-+      lock.l_len = 1L;
-+    }else{
-+      lock.l_start = SHARED_FIRST;
-+      lock.l_len = SHARED_SIZE;
-     }
- 
--    return SQLITE_OK;
-+    if( unixFileLock(pFile, &lock) ){
-+      tErrno = errno;
-+      rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
-+      if( rc!=SQLITE_BUSY ){
-+        pFile->lastErrno = tErrno;
-+      }
-+    }
-   }
--}
-+  
- 
--/*
--** Determine the current size of a file in bytes
--*/
--static int unixFileSize(sqlite3_file *id, i64 *pSize){
--  int rc;
--  struct stat buf;
--  assert( id );
--  rc = osFstat(((unixFile*)id)->h, &buf);
--  SimulateIOError( rc=1 );
--  if( rc!=0 ){
--    ((unixFile*)id)->lastErrno = errno;
--    return SQLITE_IOERR_FSTAT;
-+#ifdef SQLITE_DEBUG
-+  /* Set up the transaction-counter change checking flags when
-+  ** transitioning from a SHARED to a RESERVED lock.  The change
-+  ** from SHARED to RESERVED marks the beginning of a normal
-+  ** write operation (not a hot journal rollback).
-+  */
-+  if( rc==SQLITE_OK
-+   && pFile->eFileLock<=SHARED_LOCK
-+   && eFileLock==RESERVED_LOCK
-+  ){
-+    pFile->transCntrChng = 0;
-+    pFile->dbUpdate = 0;
-+    pFile->inNormalWrite = 1;
-   }
--  *pSize = buf.st_size;
-+#endif
- 
--  /* When opening a zero-size database, the findInodeInfo() procedure
--  ** writes a single byte into that file in order to work around a bug
--  ** in the OS-X msdos filesystem.  In order to avoid problems with upper
--  ** layers, we need to report this file size as zero even though it is
--  ** really 1.   Ticket #3260.
--  */
--  if( *pSize==1 ) *pSize = 0;
- 
-+  if( rc==SQLITE_OK ){
-+    pFile->eFileLock = eFileLock;
-+    pInode->eFileLock = eFileLock;
-+  }else if( eFileLock==EXCLUSIVE_LOCK ){
-+    pFile->eFileLock = PENDING_LOCK;
-+    pInode->eFileLock = PENDING_LOCK;
-+  }
- 
--  return SQLITE_OK;
-+end_lock:
-+  unixLeaveMutex();
-+  OSTRACE(("LOCK    %d %s %s (unix)\n", pFile->h, azFileLock(eFileLock), 
-+      rc==SQLITE_OK ? "ok" : "failed"));
-+  return rc;
- }
- 
--#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
- /*
--** Handler for proxy-locking file-control verbs.  Defined below in the
--** proxying locking division.
-+** Add the file descriptor used by file handle pFile to the corresponding
-+** pUnused list.
- */
--static int proxyFileControl(sqlite3_file*,int,void*);
--#endif
-+static void setPendingFd(unixFile *pFile){
-+  unixInodeInfo *pInode = pFile->pInode;
-+  UnixUnusedFd *p = pFile->pUnused;
-+  p->pNext = pInode->pUnused;
-+  pInode->pUnused = p;
-+  pFile->h = -1;
-+  pFile->pUnused = 0;
-+}
- 
--/* 
--** This function is called to handle the SQLITE_FCNTL_SIZE_HINT 
--** file-control operation.  Enlarge the database to nBytes in size
--** (rounded up to the next chunk-size).  If the database is already
--** nBytes or larger, this routine is a no-op.
-+/*
-+** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
-+** 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.
-+** 
-+** If handleNFSUnlock is true, then on downgrading an EXCLUSIVE_LOCK to SHARED
-+** the byte range is divided into 2 parts and the first part is unlocked then
-+** set to a read lock, then the other part is simply unlocked.  This works 
-+** around a bug in BSD NFS lockd (also seen on MacOSX 10.3+) that fails to 
-+** remove the write lock on a region when a read lock is set.
- */
--static int fcntlSizeHint(unixFile *pFile, i64 nByte){
--  if( pFile->szChunk>0 ){
--    i64 nSize;                    /* Required file size */
--    struct stat buf;              /* Used to hold return values of fstat() */
--   
--    if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT;
-+static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
-+  unixFile *pFile = (unixFile*)id;
-+  unixInodeInfo *pInode;
-+  struct flock lock;
-+  int rc = SQLITE_OK;
- 
--    nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk;
--    if( nSize>(i64)buf.st_size ){
-+  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()));
- 
--#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
--      /* The code below is handling the return value of osFallocate() 
--      ** correctly. posix_fallocate() is defined to "returns zero on success, 
--      ** or an error number on  failure". See the manpage for details. */
--      int err;
--      do{
--        err = osFallocate(pFile->h, buf.st_size, nSize-buf.st_size);
--      }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.
--      */
--      int nBlk = buf.st_blksize;  /* File-system block size */
--      i64 iWrite;                 /* Next offset to write to */
-+  assert( eFileLock<=SHARED_LOCK );
-+  if( pFile->eFileLock<=eFileLock ){
-+    return SQLITE_OK;
-+  }
-+  unixEnterMutex();
-+  pInode = pFile->pInode;
-+  assert( pInode->nShared!=0 );
-+  if( pFile->eFileLock>SHARED_LOCK ){
-+    assert( pInode->eFileLock==pFile->eFileLock );
- 
--      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);
--        if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
--        iWrite += nBlk;
-+#ifdef SQLITE_DEBUG
-+    /* When reducing a lock such that other processes can start
-+    ** reading the database file again, make sure that the
-+    ** transaction counter was updated if any part of the database
-+    ** file changed.  If the transaction counter is not updated,
-+    ** other connections to the same file might not realize that
-+    ** the file has changed and hence might not know to flush their
-+    ** cache.  The use of a stale cache can lead to database corruption.
-+    */
-+    pFile->inNormalWrite = 0;
-+#endif
-+
-+    /* downgrading to a shared lock on NFS involves clearing the write lock
-+    ** before establishing the readlock - to avoid a race condition we downgrade
-+    ** the lock in 2 blocks, so that part of the range will be covered by a 
-+    ** write lock until the rest is covered by a read lock:
-+    **  1:   [WWWWW]
-+    **  2:   [....W]
-+    **  3:   [RRRRW]
-+    **  4:   [RRRR.]
-+    */
-+    if( eFileLock==SHARED_LOCK ){
-+
-+#if !defined(__APPLE__) || !SQLITE_ENABLE_LOCKING_STYLE
-+      (void)handleNFSUnlock;
-+      assert( handleNFSUnlock==0 );
-+#endif
-+#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
-+      if( handleNFSUnlock ){
-+        int tErrno;               /* Error code from system call errors */
-+        off_t divSize = SHARED_SIZE - 1;
-+        
-+        lock.l_type = F_UNLCK;
-+        lock.l_whence = SEEK_SET;
-+        lock.l_start = SHARED_FIRST;
-+        lock.l_len = divSize;
-+        if( unixFileLock(pFile, &lock)==(-1) ){
-+          tErrno = errno;
-+          rc = SQLITE_IOERR_UNLOCK;
-+          if( IS_LOCK_ERROR(rc) ){
-+            pFile->lastErrno = tErrno;
-+          }
-+          goto end_unlock;
-+        }
-+        lock.l_type = F_RDLCK;
-+        lock.l_whence = SEEK_SET;
-+        lock.l_start = SHARED_FIRST;
-+        lock.l_len = divSize;
-+        if( unixFileLock(pFile, &lock)==(-1) ){
-+          tErrno = errno;
-+          rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK);
-+          if( IS_LOCK_ERROR(rc) ){
-+            pFile->lastErrno = tErrno;
-+          }
-+          goto end_unlock;
-+        }
-+        lock.l_type = F_UNLCK;
-+        lock.l_whence = SEEK_SET;
-+        lock.l_start = SHARED_FIRST+divSize;
-+        lock.l_len = SHARED_SIZE-divSize;
-+        if( unixFileLock(pFile, &lock)==(-1) ){
-+          tErrno = errno;
-+          rc = SQLITE_IOERR_UNLOCK;
-+          if( IS_LOCK_ERROR(rc) ){
-+            pFile->lastErrno = tErrno;
-+          }
-+          goto end_unlock;
-+        }
-+      }else
-+#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
-+      {
-+        lock.l_type = F_RDLCK;
-+        lock.l_whence = SEEK_SET;
-+        lock.l_start = SHARED_FIRST;
-+        lock.l_len = SHARED_SIZE;
-+        if( unixFileLock(pFile, &lock) ){
-+          /* In theory, the call to unixFileLock() cannot fail because another
-+          ** process is holding an incompatible lock. If it does, this 
-+          ** indicates that the other process is not following the locking
-+          ** protocol. If this happens, return SQLITE_IOERR_RDLOCK. Returning
-+          ** SQLITE_BUSY would confuse the upper layer (in practice it causes 
-+          ** an assert to fail). */ 
-+          rc = SQLITE_IOERR_RDLOCK;
-+          pFile->lastErrno = errno;
-+          goto end_unlock;
-+        }
-       }
--#endif
-+    }
-+    lock.l_type = F_UNLCK;
-+    lock.l_whence = SEEK_SET;
-+    lock.l_start = PENDING_BYTE;
-+    lock.l_len = 2L;  assert( PENDING_BYTE+1==RESERVED_BYTE );
-+    if( unixFileLock(pFile, &lock)==0 ){
-+      pInode->eFileLock = SHARED_LOCK;
-+    }else{
-+      rc = SQLITE_IOERR_UNLOCK;
-+      pFile->lastErrno = errno;
-+      goto end_unlock;
-     }
-   }
--
--  if( pFile->mmapSizeMax>0 && nByte>pFile->mmapSize ){
--    int rc;
--    if( pFile->szChunk<=0 ){
--      if( robust_ftruncate(pFile->h, nByte) ){
-+  if( eFileLock==NO_LOCK ){
-+    /* Decrement the shared lock counter.  Release the lock using an
-+    ** OS call only when all threads in this same process have released
-+    ** the lock.
-+    */
-+    pInode->nShared--;
-+    if( pInode->nShared==0 ){
-+      lock.l_type = F_UNLCK;
-+      lock.l_whence = SEEK_SET;
-+      lock.l_start = lock.l_len = 0L;
-+      if( unixFileLock(pFile, &lock)==0 ){
-+        pInode->eFileLock = NO_LOCK;
-+      }else{
-+        rc = SQLITE_IOERR_UNLOCK;
-         pFile->lastErrno = errno;
--        return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
-+        pInode->eFileLock = NO_LOCK;
-+        pFile->eFileLock = NO_LOCK;
-       }
-     }
- 
--    rc = unixMapfile(pFile, nByte);
--    return rc;
-+    /* Decrement the count of locks against this same file.  When the
-+    ** count reaches zero, close any other file descriptors whose close
-+    ** was deferred because of outstanding locks.
-+    */
-+    pInode->nLock--;
-+    assert( pInode->nLock>=0 );
-+    if( pInode->nLock==0 ){
-+      closePendingFds(pFile);
-+    }
-   }
- 
--  return SQLITE_OK;
-+end_unlock:
-+  unixLeaveMutex();
-+  if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock;
-+  return rc;
- }
- 
- /*
--** If *pArg is inititially negative then this is a query.  Set *pArg to
--** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set.
-+** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
-+** must be either NO_LOCK or SHARED_LOCK.
- **
--** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags.
-+** If the locking level of the file descriptor is already at or below
-+** the requested locking level, this routine is a no-op.
- */
--static void unixModeBit(unixFile *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 int unixUnlock(sqlite3_file *id, int eFileLock){
-+  assert( eFileLock==SHARED_LOCK || ((unixFile *)id)->nFetchOut==0 );
-+  return posixUnlock(id, eFileLock, 0);
- }
- 
--/* Forward declaration */
--static int unixGetTempname(int nBuf, char *zBuf);
-+static int unixMapfile(unixFile *pFd, i64 nByte);
-+static void unixUnmapfile(unixFile *pFd);
- 
- /*
--** Information and control of an open file handle.
-+** This function performs the parts of the "close file" operation 
-+** common to all locking schemes. It closes the directory and file
-+** handles, if they are valid, and sets all fields of the unixFile
-+** structure to 0.
-+**
-+** It is *not* necessary to hold the mutex when this routine is called,
-+** even on VxWorks.  A mutex will be acquired on VxWorks by the
-+** vxworksReleaseFileId() routine.
- */
--static int unixFileControl(sqlite3_file *id, int op, void *pArg){
-+static int closeUnixFile(sqlite3_file *id){
-   unixFile *pFile = (unixFile*)id;
--  switch( op ){
--    case SQLITE_FCNTL_LOCKSTATE: {
--      *(int*)pArg = pFile->eFileLock;
--      return SQLITE_OK;
--    }
--    case SQLITE_LAST_ERRNO: {
--      *(int*)pArg = pFile->lastErrno;
--      return SQLITE_OK;
--    }
--    case SQLITE_FCNTL_CHUNK_SIZE: {
--      pFile->szChunk = *(int *)pArg;
--      return SQLITE_OK;
--    }
--    case SQLITE_FCNTL_SIZE_HINT: {
--      int rc;
--      SimulateIOErrorBenign(1);
--      rc = fcntlSizeHint(pFile, *(i64 *)pArg);
--      SimulateIOErrorBenign(0);
--      return rc;
--    }
--    case SQLITE_FCNTL_PERSIST_WAL: {
--      unixModeBit(pFile, UNIXFILE_PERSIST_WAL, (int*)pArg);
--      return SQLITE_OK;
--    }
--    case SQLITE_FCNTL_POWERSAFE_OVERWRITE: {
--      unixModeBit(pFile, UNIXFILE_PSOW, (int*)pArg);
--      return SQLITE_OK;
--    }
--    case SQLITE_FCNTL_VFSNAME: {
--      *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
--      return SQLITE_OK;
--    }
--    case SQLITE_FCNTL_TEMPFILENAME: {
--      char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
--      if( zTFile ){
--        unixGetTempname(pFile->pVfs->mxPathname, zTFile);
--        *(char**)pArg = zTFile;
--      }
--      return SQLITE_OK;
--    }
--    case SQLITE_FCNTL_MMAP_SIZE: {
--      i64 newLimit = *(i64*)pArg;
--      if( newLimit>sqlite3GlobalConfig.mxMmap ){
--        newLimit = sqlite3GlobalConfig.mxMmap;
--      }
--      *(i64*)pArg = pFile->mmapSizeMax;
--      if( newLimit>=0 ){
--        pFile->mmapSizeMax = newLimit;
--        if( newLimit<pFile->mmapSize ) pFile->mmapSize = newLimit;
--      }
--      return SQLITE_OK;
--    }
--#ifdef SQLITE_DEBUG
--    /* The pager calls this method to signal that it has done
--    ** a rollback and that the database is therefore unchanged and
--    ** it hence it is OK for the transaction change counter to be
--    ** unchanged.
--    */
--    case SQLITE_FCNTL_DB_UNCHANGED: {
--      ((unixFile*)id)->dbUpdate = 0;
--      return SQLITE_OK;
--    }
--#endif
--#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
--    case SQLITE_SET_LOCKPROXYFILE:
--    case SQLITE_GET_LOCKPROXYFILE: {
--      return proxyFileControl(id,op,pArg);
-+  unixUnmapfile(pFile);
-+  if( pFile->h>=0 ){
-+    robust_close(pFile, pFile->h, __LINE__);
-+    pFile->h = -1;
-+  }
-+#if OS_VXWORKS
-+  if( pFile->pId ){
-+    if( pFile->ctrlFlags & UNIXFILE_DELETE ){
-+      osUnlink(pFile->pId->zCanonicalName);
-     }
--#endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */
-+    vxworksReleaseFileId(pFile->pId);
-+    pFile->pId = 0;
-   }
--  return SQLITE_NOTFOUND;
-+#endif
-+  OSTRACE(("CLOSE   %-3d\n", pFile->h));
-+  OpenCounter(-1);
-+  sqlite3_free(pFile->pUnused);
-+  memset(pFile, 0, sizeof(unixFile));
-+  return SQLITE_OK;
- }
- 
- /*
--** 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.
-+** Close a file.
- */
--#ifndef __QNXNTO__ 
--static int unixSectorSize(sqlite3_file *NotUsed){
--  UNUSED_PARAMETER(NotUsed);
--  return SQLITE_DEFAULT_SECTOR_SIZE;
-+static int unixClose(sqlite3_file *id){
-+  int rc = SQLITE_OK;
-+  unixFile *pFile = (unixFile *)id;
-+  verifyDbFile(pFile);
-+  unixUnlock(id, NO_LOCK);
-+  unixEnterMutex();
-+
-+  /* unixFile.pInode is always valid here. Otherwise, a different close
-+  ** routine (e.g. nolockClose()) would be called instead.
-+  */
-+  assert( pFile->pInode->nLock>0 || pFile->pInode->bProcessLock==0 );
-+  if( ALWAYS(pFile->pInode) && pFile->pInode->nLock ){
-+    /* If there are outstanding locks, do not actually close the file just
-+    ** yet because that would clear those locks.  Instead, add the file
-+    ** descriptor to pInode->pUnused list.  It will be automatically closed 
-+    ** when the last lock is cleared.
-+    */
-+    setPendingFd(pFile);
-+  }
-+  releaseInodeInfo(pFile);
-+  rc = closeUnixFile(id);
-+  unixLeaveMutex();
-+  return rc;
- }
--#endif
- 
--/*
--** The following version of unixSectorSize() is optimized for QNX.
-+/************** End of the posix advisory lock implementation *****************
-+******************************************************************************/
-+
-+/******************************************************************************
-+****************************** No-op Locking **********************************
-+**
-+** Of the various locking implementations available, this is by far the
-+** simplest:  locking is ignored.  No attempt is made to lock the database
-+** file for reading or writing.
-+**
-+** This locking mode is appropriate for use on read-only databases
-+** (ex: databases that are burned into CD-ROM, for example.)  It can
-+** also be used if the application employs some external mechanism to
-+** prevent simultaneous access of the same database by two or more
-+** database connections.  But there is a serious risk of database
-+** corruption if this locking mode is used in situations where multiple
-+** database connections are accessing the same database file at the same
-+** time and one or more of those connections are writing.
- */
--#ifdef __QNXNTO__
--#include <sys/dcmd_blk.h>
--#include <sys/statvfs.h>
--static int unixSectorSize(sqlite3_file *id){
--  unixFile *pFile = (unixFile*)id;
--  if( pFile->sectorSize == 0 ){
--    struct statvfs fsInfo;
--       
--    /* Set defaults for non-supported filesystems */
--    pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
--    pFile->deviceCharacteristics = 0;
--    if( fstatvfs(pFile->h, &fsInfo) == -1 ) {
--      return pFile->sectorSize;
--    }
- 
--    if( !strcmp(fsInfo.f_basetype, "tmp") ) {
--      pFile->sectorSize = fsInfo.f_bsize;
--      pFile->deviceCharacteristics =
--        SQLITE_IOCAP_ATOMIC4K |       /* All ram filesystem writes are atomic */
--        SQLITE_IOCAP_SAFE_APPEND |    /* growing the file does not occur until
--                                      ** the write succeeds */
--        SQLITE_IOCAP_SEQUENTIAL |     /* The ram filesystem has no write behind
--                                      ** so it is ordered */
--        0;
--    }else if( strstr(fsInfo.f_basetype, "etfs") ){
--      pFile->sectorSize = fsInfo.f_bsize;
--      pFile->deviceCharacteristics =
--        /* etfs cluster size writes are atomic */
--        (pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) |
--        SQLITE_IOCAP_SAFE_APPEND |    /* growing the file does not occur until
--                                      ** the write succeeds */
--        SQLITE_IOCAP_SEQUENTIAL |     /* The ram filesystem has no write behind
--                                      ** so it is ordered */
--        0;
--    }else if( !strcmp(fsInfo.f_basetype, "qnx6") ){
--      pFile->sectorSize = fsInfo.f_bsize;
--      pFile->deviceCharacteristics =
--        SQLITE_IOCAP_ATOMIC |         /* All filesystem writes are atomic */
--        SQLITE_IOCAP_SAFE_APPEND |    /* growing the file does not occur until
--                                      ** the write succeeds */
--        SQLITE_IOCAP_SEQUENTIAL |     /* The ram filesystem has no write behind
--                                      ** so it is ordered */
--        0;
--    }else if( !strcmp(fsInfo.f_basetype, "qnx4") ){
--      pFile->sectorSize = fsInfo.f_bsize;
--      pFile->deviceCharacteristics =
--        /* full bitset of atomics from max sector size and smaller */
--        ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 |
--        SQLITE_IOCAP_SEQUENTIAL |     /* The ram filesystem has no write behind
--                                      ** so it is ordered */
--        0;
--    }else if( strstr(fsInfo.f_basetype, "dos") ){
--      pFile->sectorSize = fsInfo.f_bsize;
--      pFile->deviceCharacteristics =
--        /* full bitset of atomics from max sector size and smaller */
--        ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 |
--        SQLITE_IOCAP_SEQUENTIAL |     /* The ram filesystem has no write behind
--                                      ** so it is ordered */
--        0;
--    }else{
--      pFile->deviceCharacteristics =
--        SQLITE_IOCAP_ATOMIC512 |      /* blocks are atomic */
--        SQLITE_IOCAP_SAFE_APPEND |    /* growing the file does not occur until
--                                      ** the write succeeds */
--        0;
--    }
--  }
--  /* Last chance verification.  If the sector size isn't a multiple of 512
--  ** then it isn't valid.*/
--  if( pFile->sectorSize % 512 != 0 ){
--    pFile->deviceCharacteristics = 0;
--    pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
--  }
--  return pFile->sectorSize;
-+static int nolockCheckReservedLock(sqlite3_file *NotUsed, int *pResOut){
-+  UNUSED_PARAMETER(NotUsed);
-+  *pResOut = 0;
-+  return SQLITE_OK;
-+}
-+static int nolockLock(sqlite3_file *NotUsed, int NotUsed2){
-+  UNUSED_PARAMETER2(NotUsed, NotUsed2);
-+  return SQLITE_OK;
-+}
-+static int nolockUnlock(sqlite3_file *NotUsed, int NotUsed2){
-+  UNUSED_PARAMETER2(NotUsed, NotUsed2);
-+  return SQLITE_OK;
- }
--#endif /* __QNXNTO__ */
- 
- /*
--** 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
--** 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,
--** very rare.  And asserting PSOW makes a large reduction in the amount
--** of required I/O for journaling, since a lot of padding is eliminated.
--**  Hence, while POWERSAFE_OVERWRITE is on by default, there is a file-control
--** available to turn it off and URI query parameter available to turn it off.
-+** Close the file.
- */
--static int unixDeviceCharacteristics(sqlite3_file *id){
--  unixFile *p = (unixFile*)id;
--  int rc = 0;
--#ifdef __QNXNTO__
--  if( p->sectorSize==0 ) unixSectorSize(id);
--  rc = p->deviceCharacteristics;
--#endif
--  if( p->ctrlFlags & UNIXFILE_PSOW ){
--    rc |= SQLITE_IOCAP_POWERSAFE_OVERWRITE;
--  }
--  return rc;
-+static int nolockClose(sqlite3_file *id) {
-+  return closeUnixFile(id);
- }
- 
--#ifndef SQLITE_OMIT_WAL
--
-+/******************* End of the no-op lock implementation *********************
-+******************************************************************************/
- 
--/*
--** Object used to represent an shared memory buffer.  
--**
--** When multiple threads all reference the same wal-index, each thread
--** has its own unixShm object, but they all point to a single instance
--** of this unixShmNode object.  In other words, each wal-index is opened
--** only once per process.
--**
--** Each unixShmNode object is connected to a single unixInodeInfo object.
--** We could coalesce this object into unixInodeInfo, but that would mean
--** every open file that does not use shared memory (in other words, most
--** open files) would have to carry around this extra information.  So
--** the unixInodeInfo object contains a pointer to this unixShmNode object
--** and the unixShmNode object is created only when needed.
--**
--** unixMutexHeld() must be true when creating or destroying
--** this object or while reading or writing the following fields:
--**
--**      nRef
-+/******************************************************************************
-+************************* Begin dot-file Locking ******************************
- **
--** The following fields are read-only after the object is created:
--** 
--**      fid
--**      zFilename
-+** The dotfile locking implementation uses the existence of separate lock
-+** files (really a directory) to control access to the database.  This works
-+** on just about every filesystem imaginable.  But there are serious downsides:
- **
--** Either unixShmNode.mutex must be held or unixShmNode.nRef==0 and
--** unixMutexHeld() is true when reading or writing any other field
--** in this structure.
--*/
--struct unixShmNode {
--  unixInodeInfo *pInode;     /* unixInodeInfo that owns this SHM node */
--  sqlite3_mutex *mutex;      /* Mutex to access this object */
--  char *zFilename;           /* Name of the mmapped file */
--  int h;                     /* Open file descriptor */
--  int szRegion;              /* Size of shared-memory regions */
--  u16 nRegion;               /* Size of array apRegion */
--  u8 isReadonly;             /* True if read-only */
--  char **apRegion;           /* Array of mapped shared-memory regions */
--  int nRef;                  /* Number of unixShm objects pointing to this */
--  unixShm *pFirst;           /* All unixShm objects pointing to this */
--#ifdef SQLITE_DEBUG
--  u8 exclMask;               /* Mask of exclusive locks held */
--  u8 sharedMask;             /* Mask of shared locks held */
--  u8 nextShmId;              /* Next available unixShm.id value */
--#endif
--};
--
--/*
--** Structure used internally by this VFS to record the state of an
--** open shared memory connection.
-+**    (1)  There is zero concurrency.  A single reader blocks all other
-+**         connections from reading or writing the database.
- **
--** The following fields are initialized when this object is created and
--** are read-only thereafter:
-+**    (2)  An application crash or power loss can leave stale lock files
-+**         sitting around that need to be cleared manually.
- **
--**    unixShm.pFile
--**    unixShm.id
-+** Nevertheless, a dotlock is an appropriate locking mode for use if no
-+** other locking strategy is available.
- **
--** All other fields are read/write.  The unixShm.pFile->mutex must be held
--** while accessing any read/write fields.
-+** Dotfile locking works by creating a subdirectory in the same directory as
-+** the database and with the same name but with a ".lock" extension added.
-+** The existence of a lock directory implies an EXCLUSIVE lock.  All other
-+** lock types (SHARED, RESERVED, PENDING) are mapped into EXCLUSIVE.
- */
--struct unixShm {
--  unixShmNode *pShmNode;     /* The underlying unixShmNode object */
--  unixShm *pNext;            /* Next unixShm with the same unixShmNode */
--  u8 hasMutex;               /* True if holding the unixShmNode mutex */
--  u8 id;                     /* Id of this connection within its unixShmNode */
--  u16 sharedMask;            /* Mask of shared locks held */
--  u16 exclMask;              /* Mask of exclusive locks held */
--};
- 
- /*
--** Constants used for locking
-+** The file suffix added to the data base filename in order to create the
-+** lock directory.
- */
--#define UNIX_SHM_BASE   ((22+SQLITE_SHM_NLOCK)*4)         /* first lock byte */
--#define UNIX_SHM_DMS    (UNIX_SHM_BASE+SQLITE_SHM_NLOCK)  /* deadman switch */
-+#define DOTLOCK_SUFFIX ".lock"
- 
- /*
--** Apply posix advisory locks for all bytes from ofst through ofst+n-1.
-+** 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, set *pResOut
-+** 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.
- **
--** Locks block if the mask is exactly UNIX_SHM_C and are non-blocking
--** otherwise.
-+** In dotfile locking, either a lock exists or it does not.  So in this
-+** variation of CheckReservedLock(), *pResOut is set to true if any lock
-+** is held on the file and false if the file is unlocked.
- */
--static int unixShmSystemLock(
--  unixShmNode *pShmNode, /* Apply locks to this open shared-memory segment */
--  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() */
--
--  /* Access to the unixShmNode object is serialized by the caller */
--  assert( sqlite3_mutex_held(pShmNode->mutex) || pShmNode->nRef==0 );
--
--  /* Shared locks never span more than one byte */
--  assert( n==1 || lockType!=F_RDLCK );
--
--  /* Locks are within range */
--  assert( n>=1 && n<SQLITE_SHM_NLOCK );
--
--  if( pShmNode->h>=0 ){
--    /* Initialize the locking parameters */
--    memset(&f, 0, sizeof(f));
--    f.l_type = lockType;
--    f.l_whence = SEEK_SET;
--    f.l_start = ofst;
--    f.l_len = n;
--
--    rc = osFcntl(pShmNode->h, F_SETLK, &f);
--    rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
--  }
--
--  /* Update the global lock state and do debug tracing */
--#ifdef SQLITE_DEBUG
--  { u16 mask;
--  OSTRACE(("SHM-LOCK "));
--  mask = (1<<(ofst+n)) - (1<<ofst);
--  if( rc==SQLITE_OK ){
--    if( lockType==F_UNLCK ){
--      OSTRACE(("unlock %d ok", ofst));
--      pShmNode->exclMask &= ~mask;
--      pShmNode->sharedMask &= ~mask;
--    }else if( lockType==F_RDLCK ){
--      OSTRACE(("read-lock %d ok", ofst));
--      pShmNode->exclMask &= ~mask;
--      pShmNode->sharedMask |= mask;
--    }else{
--      assert( lockType==F_WRLCK );
--      OSTRACE(("write-lock %d ok", ofst));
--      pShmNode->exclMask |= mask;
--      pShmNode->sharedMask &= ~mask;
--    }
--  }else{
--    if( lockType==F_UNLCK ){
--      OSTRACE(("unlock %d failed", ofst));
--    }else if( lockType==F_RDLCK ){
--      OSTRACE(("read-lock failed"));
--    }else{
--      assert( lockType==F_WRLCK );
--      OSTRACE(("write-lock %d failed", ofst));
--    }
--  }
--  OSTRACE((" - afterwards %03x,%03x\n",
--           pShmNode->sharedMask, pShmNode->exclMask));
--  }
--#endif
--
--  return rc;        
--}
-+static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) {
-+  int rc = SQLITE_OK;
-+  int reserved = 0;
-+  unixFile *pFile = (unixFile*)id;
- 
-+  SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
-+  
-+  assert( pFile );
- 
--/*
--** Purge the unixShmNodeList list of all entries with unixShmNode.nRef==0.
--**
--** This is not a VFS shared-memory method; it is a utility function called
--** by VFS shared-memory methods.
--*/
--static void unixShmPurge(unixFile *pFd){
--  unixShmNode *p = pFd->pInode->pShmNode;
--  assert( unixMutexHeld() );
--  if( p && p->nRef==0 ){
--    int i;
--    assert( p->pInode==pFd->pInode );
--    sqlite3_mutex_free(p->mutex);
--    for(i=0; i<p->nRegion; i++){
--      if( p->h>=0 ){
--        osMunmap(p->apRegion[i], p->szRegion);
--      }else{
--        sqlite3_free(p->apRegion[i]);
--      }
--    }
--    sqlite3_free(p->apRegion);
--    if( p->h>=0 ){
--      robust_close(pFd, p->h, __LINE__);
--      p->h = -1;
--    }
--    p->pInode->pShmNode = 0;
--    sqlite3_free(p);
-+  /* Check if a thread in this process holds such a lock */
-+  if( pFile->eFileLock>SHARED_LOCK ){
-+    /* Either this connection or some other connection in the same process
-+    ** holds a lock on the file.  No need to check further. */
-+    reserved = 1;
-+  }else{
-+    /* The lock is held if and only if the lockfile exists */
-+    const char *zLockFile = (const char*)pFile->lockingContext;
-+    reserved = osAccess(zLockFile, 0)==0;
-   }
-+  OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved));
-+  *pResOut = reserved;
-+  return rc;
- }
- 
- /*
--** Open a shared-memory area associated with open database file pDbFd.  
--** This particular implementation uses mmapped files.
-+** Lock the file with the lock specified by parameter eFileLock - one
-+** of the following:
- **
--** The file used to implement shared-memory is in the same directory
--** as the open database file and has the same name as the open database
--** file with the "-shm" suffix added.  For example, if the database file
--** is "/home/user1/config.db" then the file that is created and mmapped
--** for shared memory will be called "/home/user1/config.db-shm".  
-+**     (1) SHARED_LOCK
-+**     (2) RESERVED_LOCK
-+**     (3) PENDING_LOCK
-+**     (4) EXCLUSIVE_LOCK
- **
--** Another approach to is to use files in /dev/shm or /dev/tmp or an
--** some other tmpfs mount. But if a file in a different directory
--** from the database file is used, then differing access permissions
--** or a chroot() might cause two different processes on the same
--** database to end up using different files for shared memory - 
--** meaning that their memory would not really be shared - resulting
--** in database corruption.  Nevertheless, this tmpfs file usage
--** can be enabled at compile-time using -DSQLITE_SHM_DIRECTORY="/dev/shm"
--** or the equivalent.  The use of the SQLITE_SHM_DIRECTORY compile-time
--** option results in an incompatible build of SQLite;  builds of SQLite
--** that with differing SQLITE_SHM_DIRECTORY settings attempt to use the
--** same database file at the same time, database corruption will likely
--** result. The SQLITE_SHM_DIRECTORY compile-time option is considered
--** "unsupported" and may go away in a future SQLite release.
-+** 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:
- **
--** 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.
-+**    UNLOCKED -> SHARED
-+**    SHARED -> RESERVED
-+**    SHARED -> (PENDING) -> EXCLUSIVE
-+**    RESERVED -> (PENDING) -> EXCLUSIVE
-+**    PENDING -> EXCLUSIVE
- **
--** If the original database file (pDbFd) is using the "unix-excl" VFS
--** that means that an exclusive lock is held on the database file and
--** that no other processes are able to read or write the database.  In
--** that case, we do not really need shared memory.  No shared memory
--** file is created.  The shared memory will be simulated with heap memory.
-+** This routine will only increase a lock.  Use the sqlite3OsUnlock()
-+** routine to lower a locking level.
-+**
-+** With dotfile locking, we really only support state (4): EXCLUSIVE.
-+** But we track the other locking levels internally.
- */
--static int unixOpenSharedMemory(unixFile *pDbFd){
--  struct unixShm *p = 0;          /* The connection to be opened */
--  struct unixShmNode *pShmNode;   /* The underlying mmapped file */
--  int rc;                         /* Result code */
--  unixInodeInfo *pInode;          /* The inode of fd */
--  char *zShmFilename;             /* Name of the file used for SHM */
--  int nShmFilename;               /* Size of the SHM filename in bytes */
-+static int dotlockLock(sqlite3_file *id, int eFileLock) {
-+  unixFile *pFile = (unixFile*)id;
-+  char *zLockFile = (char *)pFile->lockingContext;
-+  int rc = SQLITE_OK;
- 
--  /* Allocate space for the new unixShm object. */
--  p = sqlite3_malloc( sizeof(*p) );
--  if( p==0 ) return SQLITE_NOMEM;
--  memset(p, 0, sizeof(*p));
--  assert( pDbFd->pShm==0 );
- 
--  /* Check to see if a unixShmNode object already exists. Reuse an existing
--  ** one if present. Create a new one if necessary.
-+  /* If we have any lock, then the lock file already exists.  All we have
-+  ** to do is adjust our internal record of the lock level.
-   */
--  unixEnterMutex();
--  pInode = pDbFd->pInode;
--  pShmNode = pInode->pShmNode;
--  if( pShmNode==0 ){
--    struct stat sStat;                 /* fstat() info for database file */
--
--    /* 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
--    ** with the same permissions.
--    */
--    if( osFstat(pDbFd->h, &sStat) && pInode->bProcessLock==0 ){
--      rc = SQLITE_IOERR_FSTAT;
--      goto shm_open_err;
--    }
--
--#ifdef SQLITE_SHM_DIRECTORY
--    nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 31;
--#else
--    nShmFilename = 6 + (int)strlen(pDbFd->zPath);
--#endif
--    pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nShmFilename );
--    if( pShmNode==0 ){
--      rc = SQLITE_NOMEM;
--      goto shm_open_err;
--    }
--    memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename);
--    zShmFilename = pShmNode->zFilename = (char*)&pShmNode[1];
--#ifdef SQLITE_SHM_DIRECTORY
--    sqlite3_snprintf(nShmFilename, zShmFilename, 
--                     SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x",
--                     (u32)sStat.st_ino, (u32)sStat.st_dev);
-+  if( pFile->eFileLock > NO_LOCK ){
-+    pFile->eFileLock = eFileLock;
-+    /* Always update the timestamp on the old file */
-+#ifdef HAVE_UTIME
-+    utime(zLockFile, NULL);
- #else
--    sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", pDbFd->zPath);
--    sqlite3FileSuffix3(pDbFd->zPath, zShmFilename);
-+    utimes(zLockFile, NULL);
- #endif
--    pShmNode->h = -1;
--    pDbFd->pInode->pShmNode = pShmNode;
--    pShmNode->pInode = pDbFd->pInode;
--    pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
--    if( pShmNode->mutex==0 ){
--      rc = SQLITE_NOMEM;
--      goto shm_open_err;
--    }
--
--    if( pInode->bProcessLock==0 ){
--      int openFlags = O_RDWR | O_CREAT;
--      if( sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
--        openFlags = O_RDONLY;
--        pShmNode->isReadonly = 1;
--      }
--      pShmNode->h = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777));
--      if( pShmNode->h<0 ){
--        rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
--        goto shm_open_err;
--      }
--
--      /* If this process is running as root, make sure that the SHM file
--      ** is owned by the same user that owns the original database.  Otherwise,
--      ** the original owner will not be able to connect.
--      */
--      osFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
-+    return SQLITE_OK;
-+  }
-   
--      /* Check to see if another process is holding the dead-man switch.
--      ** If not, truncate the file to zero length. 
--      */
--      rc = SQLITE_OK;
--      if( unixShmSystemLock(pShmNode, 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);
-+  /* grab an exclusive lock */
-+  rc = osMkdir(zLockFile, 0777);
-+  if( rc<0 ){
-+    /* failed to open/create the lock directory */
-+    int tErrno = errno;
-+    if( EEXIST == tErrno ){
-+      rc = SQLITE_BUSY;
-+    } else {
-+      rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
-+      if( IS_LOCK_ERROR(rc) ){
-+        pFile->lastErrno = tErrno;
-       }
--      if( rc ) goto shm_open_err;
-     }
--  }
--
--  /* Make the new connection a child of the unixShmNode */
--  p->pShmNode = pShmNode;
--#ifdef SQLITE_DEBUG
--  p->id = pShmNode->nextShmId++;
--#endif
--  pShmNode->nRef++;
--  pDbFd->pShm = p;
--  unixLeaveMutex();
--
--  /* The reference count on pShmNode has already been incremented under
--  ** the cover of the unixEnterMutex() mutex and the pointer from the
--  ** new (struct unixShm) 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:
--  unixShmPurge(pDbFd);       /* This call frees pShmNode if required */
--  sqlite3_free(p);
--  unixLeaveMutex();
-+    return rc;
-+  } 
-+  
-+  /* got it, set the type and return ok */
-+  pFile->eFileLock = eFileLock;
-   return rc;
- }
- 
- /*
--** 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.
-+** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
-+** must be either NO_LOCK or SHARED_LOCK.
- **
--** Otherwise, if the bExtend 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 
--** bExtend is non-zero and the requested shared-memory region has not yet 
--** been allocated, it is allocated by this function.
-+** If the locking level of the file descriptor is already at or below
-+** the requested locking level, this routine is a no-op.
- **
--** 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.
-+** When the locking level reaches NO_LOCK, delete the lock file.
- */
--static int unixShmMap(
--  sqlite3_file *fd,               /* Handle open on database file */
--  int iRegion,                    /* Region to retrieve */
--  int szRegion,                   /* Size of regions */
--  int bExtend,                    /* True to extend file if necessary */
--  void volatile **pp              /* OUT: Mapped memory */
--){
--  unixFile *pDbFd = (unixFile*)fd;
--  unixShm *p;
--  unixShmNode *pShmNode;
--  int rc = SQLITE_OK;
-+static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
-+  unixFile *pFile = (unixFile*)id;
-+  char *zLockFile = (char *)pFile->lockingContext;
-+  int rc;
- 
--  /* If the shared-memory file has not yet been opened, open it now. */
--  if( pDbFd->pShm==0 ){
--    rc = unixOpenSharedMemory(pDbFd);
--    if( rc!=SQLITE_OK ) return rc;
-+  assert( pFile );
-+  OSTRACE(("UNLOCK  %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock,
-+           pFile->eFileLock, getpid()));
-+  assert( eFileLock<=SHARED_LOCK );
-+  
-+  /* no-op if possible */
-+  if( pFile->eFileLock==eFileLock ){
-+    return SQLITE_OK;
-   }
- 
--  p = pDbFd->pShm;
--  pShmNode = p->pShmNode;
--  sqlite3_mutex_enter(pShmNode->mutex);
--  assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
--  assert( pShmNode->pInode==pDbFd->pInode );
--  assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
--  assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
--
--  if( pShmNode->nRegion<=iRegion ){
--    char **apNew;                      /* New apRegion[] array */
--    int nByte = (iRegion+1)*szRegion;  /* Minimum required file size */
--    struct stat sStat;                 /* Used by fstat() */
--
--    pShmNode->szRegion = szRegion;
--
--    if( pShmNode->h>=0 ){
--      /* 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).
--      */
--      if( osFstat(pShmNode->h, &sStat) ){
--        rc = SQLITE_IOERR_SHMSIZE;
--        goto shmpage_out;
--      }
-+  /* To downgrade to shared, simply update our internal notion of the
-+  ** lock state.  No need to mess with the file on disk.
-+  */
-+  if( eFileLock==SHARED_LOCK ){
-+    pFile->eFileLock = SHARED_LOCK;
-+    return SQLITE_OK;
-+  }
-   
--      if( sStat.st_size<nByte ){
--        /* The requested memory region does not exist. If bExtend is set to
--        ** false, exit early. *pp will be set to NULL and SQLITE_OK returned.
--        */
--        if( !bExtend ){
--          goto shmpage_out;
--        }
--
--        /* Alternatively, if bExtend is true, extend the file. Do this by
--        ** writing a single byte to the end of each (OS) page being
--        ** allocated or extended. Technically, we need only write to the
--        ** last page in order to extend the file. But writing to all new
--        ** pages forces the OS to allocate them immediately, which reduces
--        ** the chances of SIGBUS while accessing the mapped region later on.
--        */
--        else{
--          static const int pgsz = 4096;
--          int iPg;
--
--          /* Write to the last byte of each newly allocated or extended page */
--          assert( (nByte % pgsz)==0 );
--          for(iPg=(sStat.st_size/pgsz); iPg<(nByte/pgsz); iPg++){
--            if( seekAndWriteFd(pShmNode->h, iPg*pgsz + pgsz-1, "", 1, 0)!=1 ){
--              const char *zFile = pShmNode->zFilename;
--              rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile);
--              goto shmpage_out;
--            }
--          }
--        }
--      }
--    }
--
--    /* Map the requested memory region into this processes address space. */
--    apNew = (char **)sqlite3_realloc(
--        pShmNode->apRegion, (iRegion+1)*sizeof(char *)
--    );
--    if( !apNew ){
--      rc = SQLITE_IOERR_NOMEM;
--      goto shmpage_out;
-+  /* To fully unlock the database, delete the lock file */
-+  assert( eFileLock==NO_LOCK );
-+  rc = osRmdir(zLockFile);
-+  if( rc<0 && errno==ENOTDIR ) rc = osUnlink(zLockFile);
-+  if( rc<0 ){
-+    int tErrno = errno;
-+    rc = 0;
-+    if( ENOENT != tErrno ){
-+      rc = SQLITE_IOERR_UNLOCK;
-     }
--    pShmNode->apRegion = apNew;
--    while(pShmNode->nRegion<=iRegion){
--      void *pMem;
--      if( pShmNode->h>=0 ){
--        pMem = osMmap(0, szRegion,
--            pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, 
--            MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
--        );
--        if( pMem==MAP_FAILED ){
--          rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename);
--          goto shmpage_out;
--        }
--      }else{
--        pMem = sqlite3_malloc(szRegion);
--        if( pMem==0 ){
--          rc = SQLITE_NOMEM;
--          goto shmpage_out;
--        }
--        memset(pMem, 0, szRegion);
--      }
--      pShmNode->apRegion[pShmNode->nRegion] = pMem;
--      pShmNode->nRegion++;
-+    if( IS_LOCK_ERROR(rc) ){
-+      pFile->lastErrno = tErrno;
-     }
-+    return rc; 
-   }
-+  pFile->eFileLock = NO_LOCK;
-+  return SQLITE_OK;
-+}
- 
--shmpage_out:
--  if( pShmNode->nRegion>iRegion ){
--    *pp = pShmNode->apRegion[iRegion];
--  }else{
--    *pp = 0;
-+/*
-+** Close a file.  Make sure the lock has been released before closing.
-+*/
-+static int dotlockClose(sqlite3_file *id) {
-+  int rc = SQLITE_OK;
-+  if( id ){
-+    unixFile *pFile = (unixFile*)id;
-+    dotlockUnlock(id, NO_LOCK);
-+    sqlite3_free(pFile->lockingContext);
-+    rc = closeUnixFile(id);
-   }
--  if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY;
--  sqlite3_mutex_leave(pShmNode->mutex);
-   return rc;
- }
-+/****************** End of the dot-file lock implementation *******************
-+******************************************************************************/
- 
--/*
--** Change the lock state for a shared-memory segment.
-+/******************************************************************************
-+************************** Begin flock Locking ********************************
- **
--** Note that the relationship between SHAREd and EXCLUSIVE locks is a little
--** different here than in posix.  In xShmLock(), one can go from unlocked
--** to shared and back or from unlocked to exclusive and back.  But one may
--** not go from shared to exclusive or from exclusive to shared.
-+** Use the flock() system call to do file locking.
-+**
-+** flock() locking is like dot-file locking in that the various
-+** fine-grain locking levels supported by SQLite are collapsed into
-+** a single exclusive lock.  In other words, SHARED, RESERVED, and
-+** PENDING locks are the same thing as an EXCLUSIVE lock.  SQLite
-+** 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.
- */
--static int unixShmLock(
--  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 */
--){
--  unixFile *pDbFd = (unixFile*)fd;      /* Connection holding shared memory */
--  unixShm *p = pDbFd->pShm;             /* The shared memory being locked */
--  unixShm *pX;                          /* For looping over all siblings */
--  unixShmNode *pShmNode = p->pShmNode;  /* The underlying file iNode */
--  int rc = SQLITE_OK;                   /* Result code */
--  u16 mask;                             /* Mask of locks to take or release */
--
--  assert( pShmNode==pDbFd->pInode->pShmNode );
--  assert( pShmNode->pInode==pDbFd->pInode );
--  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 );
--  assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
--  assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
--
--  mask = (1<<(ofst+n)) - (1<<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 */
--
--    /* 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;
--    }
--
--    /* Unlock the system-level locks */
--    if( (mask & allMask)==0 ){
--      rc = unixShmSystemLock(pShmNode, F_UNLCK, ofst+UNIX_SHM_BASE, n);
--    }else{
--      rc = SQLITE_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" */
--
--    /* 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;
--    }
-+#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
- 
--    /* 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);
--      }else{
--        rc = SQLITE_OK;
--      }
--    }
-+/*
-+** Retry flock() calls that fail with EINTR
-+*/
-+#ifdef EINTR
-+static int robust_flock(int fd, int op){
-+  int rc;
-+  do{ rc = flock(fd,op); }while( rc<0 && errno==EINTR );
-+  return rc;
-+}
-+#else
-+# define robust_flock(a,b) flock(a,b)
-+#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;
--      }
--    }
-+/*
-+** 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, set *pResOut
-+** 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 flockCheckReservedLock(sqlite3_file *id, int *pResOut){
-+  int rc = SQLITE_OK;
-+  int reserved = 0;
-+  unixFile *pFile = (unixFile*)id;
-   
--    /* Get the exclusive locks at the system level.  Then if successful
--    ** also mark the local connection as being locked.
--    */
--    if( rc==SQLITE_OK ){
--      rc = unixShmSystemLock(pShmNode, F_WRLCK, ofst+UNIX_SHM_BASE, n);
--      if( rc==SQLITE_OK ){
--        assert( (p->sharedMask & mask)==0 );
--        p->exclMask |= mask;
-+  SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
-+  
-+  assert( pFile );
-+  
-+  /* Check if a thread in this process holds such a lock */
-+  if( pFile->eFileLock>SHARED_LOCK ){
-+    reserved = 1;
-+  }
-+  
-+  /* Otherwise see if some other process holds it. */
-+  if( !reserved ){
-+    /* attempt to get the lock */
-+    int lrc = robust_flock(pFile->h, LOCK_EX | LOCK_NB);
-+    if( !lrc ){
-+      /* got the lock, unlock it */
-+      lrc = robust_flock(pFile->h, LOCK_UN);
-+      if ( lrc ) {
-+        int tErrno = errno;
-+        /* unlock failed with an error */
-+        lrc = SQLITE_IOERR_UNLOCK; 
-+        if( IS_LOCK_ERROR(lrc) ){
-+          pFile->lastErrno = tErrno;
-+          rc = lrc;
-+        }
-+      }
-+    } else {
-+      int tErrno = errno;
-+      reserved = 1;
-+      /* someone else might have it reserved */
-+      lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); 
-+      if( IS_LOCK_ERROR(lrc) ){
-+        pFile->lastErrno = tErrno;
-+        rc = lrc;
-       }
-     }
-   }
--  sqlite3_mutex_leave(pShmNode->mutex);
--  OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
--           p->id, getpid(), p->sharedMask, p->exclMask));
-+  OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved));
-+
-+#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
-+  if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){
-+    rc = SQLITE_OK;
-+    reserved=1;
-+  }
-+#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
-+  *pResOut = reserved;
-   return rc;
- }
- 
- /*
--** Implement a memory barrier or memory fence on shared memory.  
-+** Lock the file with the lock specified by parameter eFileLock - one
-+** of the following:
- **
--** All loads and stores begun before the barrier must complete before
--** any load or store begun after the barrier.
--*/
--static void unixShmBarrier(
--  sqlite3_file *fd                /* Database file holding the shared memory */
--){
--  UNUSED_PARAMETER(fd);
--  unixEnterMutex();
--  unixLeaveMutex();
--}
--
--/*
--** Close a connection to shared-memory.  Delete the underlying 
--** storage if deleteFlag is true.
-+**     (1) SHARED_LOCK
-+**     (2) RESERVED_LOCK
-+**     (3) PENDING_LOCK
-+**     (4) EXCLUSIVE_LOCK
- **
--** If there is no shared memory associated with the connection then this
--** routine is a harmless no-op.
-+** 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
-+**
-+** flock() only really support EXCLUSIVE locks.  We track intermediate
-+** lock states in the sqlite3_file structure, but all locks SHARED or
-+** above are really EXCLUSIVE locks and exclude all other processes from
-+** access the file.
-+**
-+** This routine will only increase a lock.  Use the sqlite3OsUnlock()
-+** routine to lower a locking level.
- */
--static int unixShmUnmap(
--  sqlite3_file *fd,               /* The underlying database file */
--  int deleteFlag                  /* Delete shared-memory if true */
--){
--  unixShm *p;                     /* The connection to be closed */
--  unixShmNode *pShmNode;          /* The underlying shared-memory file */
--  unixShm **pp;                   /* For looping over sibling connections */
--  unixFile *pDbFd;                /* The underlying database file */
--
--  pDbFd = (unixFile*)fd;
--  p = pDbFd->pShm;
--  if( p==0 ) return SQLITE_OK;
--  pShmNode = p->pShmNode;
--
--  assert( pShmNode==pDbFd->pInode->pShmNode );
--  assert( pShmNode->pInode==pDbFd->pInode );
--
--  /* 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;
-+static int flockLock(sqlite3_file *id, int eFileLock) {
-+  int rc = SQLITE_OK;
-+  unixFile *pFile = (unixFile*)id;
- 
--  /* Free the connection p */
--  sqlite3_free(p);
--  pDbFd->pShm = 0;
--  sqlite3_mutex_leave(pShmNode->mutex);
-+  assert( pFile );
- 
--  /* If pShmNode->nRef has reached 0, then close the underlying
--  ** shared-memory file, too */
--  unixEnterMutex();
--  assert( pShmNode->nRef>0 );
--  pShmNode->nRef--;
--  if( pShmNode->nRef==0 ){
--    if( deleteFlag && pShmNode->h>=0 ) osUnlink(pShmNode->zFilename);
--    unixShmPurge(pDbFd);
-+  /* if we already have a lock, it is exclusive.  
-+  ** Just adjust level and punt on outta here. */
-+  if (pFile->eFileLock > NO_LOCK) {
-+    pFile->eFileLock = eFileLock;
-+    return SQLITE_OK;
-   }
--  unixLeaveMutex();
--
--  return SQLITE_OK;
-+  
-+  /* grab an exclusive lock */
-+  
-+  if (robust_flock(pFile->h, LOCK_EX | LOCK_NB)) {
-+    int tErrno = errno;
-+    /* didn't get, must be busy */
-+    rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
-+    if( IS_LOCK_ERROR(rc) ){
-+      pFile->lastErrno = tErrno;
-+    }
-+  } else {
-+    /* got it, set the type and return ok */
-+    pFile->eFileLock = eFileLock;
-+  }
-+  OSTRACE(("LOCK    %d %s %s (flock)\n", pFile->h, azFileLock(eFileLock), 
-+           rc==SQLITE_OK ? "ok" : "failed"));
-+#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
-+  if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){
-+    rc = SQLITE_BUSY;
-+  }
-+#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
-+  return rc;
- }
- 
- 
--#else
--# define unixShmMap     0
--# define unixShmLock    0
--# define unixShmBarrier 0
--# define unixShmUnmap   0
--#endif /* #ifndef SQLITE_OMIT_WAL */
--
- /*
--** If it is currently memory mapped, unmap file pFd.
-+** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
-+** 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.
- */
--static void unixUnmapfile(unixFile *pFd){
--  assert( pFd->nFetchOut==0 );
--#if SQLITE_MAX_MMAP_SIZE>0
--  if( pFd->pMapRegion ){
--    osMunmap(pFd->pMapRegion, pFd->mmapSizeActual);
--    pFd->pMapRegion = 0;
--    pFd->mmapSize = 0;
--    pFd->mmapSizeActual = 0;
-+static int flockUnlock(sqlite3_file *id, int eFileLock) {
-+  unixFile *pFile = (unixFile*)id;
-+  
-+  assert( pFile );
-+  OSTRACE(("UNLOCK  %d %d was %d pid=%d (flock)\n", pFile->h, eFileLock,
-+           pFile->eFileLock, getpid()));
-+  assert( eFileLock<=SHARED_LOCK );
-+  
-+  /* no-op if possible */
-+  if( pFile->eFileLock==eFileLock ){
-+    return SQLITE_OK;
-+  }
-+  
-+  /* shared can just be set because we always have an exclusive */
-+  if (eFileLock==SHARED_LOCK) {
-+    pFile->eFileLock = eFileLock;
-+    return SQLITE_OK;
-+  }
-+  
-+  /* no, really, unlock. */
-+  if( robust_flock(pFile->h, LOCK_UN) ){
-+#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
-+    return SQLITE_OK;
-+#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
-+    return SQLITE_IOERR_UNLOCK;
-+  }else{
-+    pFile->eFileLock = NO_LOCK;
-+    return SQLITE_OK;
-   }
--#endif
- }
- 
--#if SQLITE_MAX_MMAP_SIZE>0
- /*
--** Return the system page size.
-+** Close a file.
- */
--static int unixGetPagesize(void){
--#if HAVE_MREMAP
--  return 512;
--#elif defined(_BSD_SOURCE)
--  return getpagesize();
--#else
--  return (int)sysconf(_SC_PAGESIZE);
--#endif
-+static int flockClose(sqlite3_file *id) {
-+  int rc = SQLITE_OK;
-+  if( id ){
-+    flockUnlock(id, NO_LOCK);
-+    rc = closeUnixFile(id);
-+  }
-+  return rc;
- }
--#endif /* SQLITE_MAX_MMAP_SIZE>0 */
- 
--#if SQLITE_MAX_MMAP_SIZE>0
--/*
--** Attempt to set the size of the memory mapping maintained by file 
--** descriptor pFd to nNew bytes. Any existing mapping is discarded.
--**
--** If successful, this function sets the following variables:
-+#endif /* SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORK */
-+
-+/******************* End of the flock lock implementation *********************
-+******************************************************************************/
-+
-+/******************************************************************************
-+************************ Begin Named Semaphore Locking ************************
- **
--**       unixFile.pMapRegion
--**       unixFile.mmapSize
--**       unixFile.mmapSizeActual
-+** Named semaphore locking is only supported on VxWorks.
- **
--** If unsuccessful, an error message is logged via sqlite3_log() and
--** the three variables above are zeroed. In this case SQLite should
--** continue accessing the database using the xRead() and xWrite()
--** methods.
-+** Semaphore locking is like dot-lock and flock in that it really only
-+** supports EXCLUSIVE locking.  Only a single process can read or write
-+** the database file at a time.  This reduces potential concurrency, but
-+** makes the lock implementation much easier.
- */
--static void unixRemapfile(
--  unixFile *pFd,                  /* File descriptor object */
--  i64 nNew                        /* Required mapping size */
--){
--  const char *zErr = "mmap";
--  int h = pFd->h;                      /* File descriptor open on db file */
--  u8 *pOrig = (u8 *)pFd->pMapRegion;   /* Pointer to current file mapping */
--  i64 nOrig = pFd->mmapSizeActual;     /* Size of pOrig region in bytes */
--  u8 *pNew = 0;                        /* Location of new mapping */
--  int flags = PROT_READ;               /* Flags to pass to mmap() */
--
--  assert( pFd->nFetchOut==0 );
--  assert( nNew>pFd->mmapSize );
--  assert( nNew<=pFd->mmapSizeMax );
--  assert( nNew>0 );
--  assert( pFd->mmapSizeActual>=pFd->mmapSize );
--  assert( MAP_FAILED!=0 );
-+#if OS_VXWORKS
- 
--  if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE;
-+/*
-+** 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, set *pResOut
-+** 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) {
-+  int rc = SQLITE_OK;
-+  int reserved = 0;
-+  unixFile *pFile = (unixFile*)id;
- 
--  if( pOrig ){
--    const int szSyspage = unixGetPagesize();
--    i64 nReuse = (pFd->mmapSize & ~(szSyspage-1));
--    u8 *pReq = &pOrig[nReuse];
-+  SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
-+  
-+  assert( pFile );
- 
--    /* Unmap any pages of the existing mapping that cannot be reused. */
--    if( nReuse!=nOrig ){
--      osMunmap(pReq, nOrig-nReuse);
--    }
-+  /* Check if a thread in this process holds such a lock */
-+  if( pFile->eFileLock>SHARED_LOCK ){
-+    reserved = 1;
-+  }
-+  
-+  /* Otherwise see if some other process holds it. */
-+  if( !reserved ){
-+    sem_t *pSem = pFile->pInode->pSem;
-+    struct stat statBuf;
- 
--#if HAVE_MREMAP
--    pNew = osMremap(pOrig, nReuse, nNew, MREMAP_MAYMOVE);
--    zErr = "mremap";
--#else
--    pNew = osMmap(pReq, nNew-nReuse, flags, MAP_SHARED, h, nReuse);
--    if( pNew!=MAP_FAILED ){
--      if( pNew!=pReq ){
--        osMunmap(pNew, nNew - nReuse);
--        pNew = 0;
--      }else{
--        pNew = pOrig;
-+    if( sem_trywait(pSem)==-1 ){
-+      int tErrno = errno;
-+      if( EAGAIN != tErrno ){
-+        rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK);
-+        pFile->lastErrno = tErrno;
-+      } else {
-+        /* someone else has the lock when we are in NO_LOCK */
-+        reserved = (pFile->eFileLock < SHARED_LOCK);
-       }
-+    }else{
-+      /* we could have it if we want it */
-+      sem_post(pSem);
-     }
--#endif
--
--    /* The attempt to extend the existing mapping failed. Free it. */
--    if( pNew==MAP_FAILED || pNew==0 ){
--      osMunmap(pOrig, nReuse);
--    }
--  }
--
--  /* If pNew is still NULL, try to create an entirely new mapping. */
--  if( pNew==0 ){
--    pNew = osMmap(0, nNew, flags, MAP_SHARED, h, 0);
-   }
-+  OSTRACE(("TEST WR-LOCK %d %d %d (sem)\n", pFile->h, rc, reserved));
- 
--  if( pNew==MAP_FAILED ){
--    pNew = 0;
--    nNew = 0;
--    unixLogError(SQLITE_OK, zErr, pFd->zPath);
--
--    /* If the mmap() above failed, assume that all subsequent mmap() calls
--    ** will probably fail too. Fall back to using xRead/xWrite exclusively
--    ** in this case.  */
--    pFd->mmapSizeMax = 0;
--  }
--  pFd->pMapRegion = (void *)pNew;
--  pFd->mmapSize = pFd->mmapSizeActual = nNew;
-+  *pResOut = reserved;
-+  return rc;
- }
--#endif
- 
- /*
--** 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.
-+** Lock the file with the lock specified by parameter eFileLock - one
-+** of the following:
- **
--** 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_LIMIT, whichever is smaller.
-+**     (1) SHARED_LOCK
-+**     (2) RESERVED_LOCK
-+**     (3) PENDING_LOCK
-+**     (4) EXCLUSIVE_LOCK
- **
--** 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.
-+** 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
-+**
-+** Semaphore locks only really support EXCLUSIVE locks.  We track intermediate
-+** lock states in the sqlite3_file structure, but all locks SHARED or
-+** above are really EXCLUSIVE locks and exclude all other processes from
-+** access the file.
-+**
-+** This routine will only increase a lock.  Use the sqlite3OsUnlock()
-+** routine to lower a locking level.
- */
--static int unixMapfile(unixFile *pFd, i64 nByte){
--#if SQLITE_MAX_MMAP_SIZE>0
--  i64 nMap = nByte;
--  int rc;
--
--  assert( nMap>=0 || pFd->nFetchOut==0 );
--  if( pFd->nFetchOut>0 ) return SQLITE_OK;
-+static int semLock(sqlite3_file *id, int eFileLock) {
-+  unixFile *pFile = (unixFile*)id;
-+  int fd;
-+  sem_t *pSem = pFile->pInode->pSem;
-+  int rc = SQLITE_OK;
- 
--  if( nMap<0 ){
--    struct stat statbuf;          /* Low-level file information */
--    rc = osFstat(pFd->h, &statbuf);
--    if( rc!=SQLITE_OK ){
--      return SQLITE_IOERR_FSTAT;
--    }
--    nMap = statbuf.st_size;
-+  /* if we already have a lock, it is exclusive.  
-+  ** Just adjust level and punt on outta here. */
-+  if (pFile->eFileLock > NO_LOCK) {
-+    pFile->eFileLock = eFileLock;
-+    rc = SQLITE_OK;
-+    goto sem_end_lock;
-   }
--  if( nMap>pFd->mmapSizeMax ){
--    nMap = pFd->mmapSizeMax;
-+  
-+  /* lock semaphore now but bail out when already locked. */
-+  if( sem_trywait(pSem)==-1 ){
-+    rc = SQLITE_BUSY;
-+    goto sem_end_lock;
-   }
- 
--  if( nMap!=pFd->mmapSize ){
--    if( nMap>0 ){
--      unixRemapfile(pFd, nMap);
--    }else{
--      unixUnmapfile(pFd);
--    }
--  }
--#endif
-+  /* got it, set the type and return ok */
-+  pFile->eFileLock = eFileLock;
- 
--  return SQLITE_OK;
-+ sem_end_lock:
-+  return rc;
- }
- 
- /*
--** 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.
-+** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
-+** must be either NO_LOCK or SHARED_LOCK.
- **
--** If this function does return a pointer, the caller must eventually 
--** release the reference by calling unixUnfetch().
-+** 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 unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
--#if SQLITE_MAX_MMAP_SIZE>0
--  unixFile *pFd = (unixFile *)fd;   /* The underlying database file */
--#endif
--  *pp = 0;
-+static int semUnlock(sqlite3_file *id, int eFileLock) {
-+  unixFile *pFile = (unixFile*)id;
-+  sem_t *pSem = pFile->pInode->pSem;
- 
--#if SQLITE_MAX_MMAP_SIZE>0
--  if( pFd->mmapSizeMax>0 ){
--    if( pFd->pMapRegion==0 ){
--      int rc = unixMapfile(pFd, -1);
--      if( rc!=SQLITE_OK ) return rc;
--    }
--    if( pFd->mmapSize >= iOff+nAmt ){
--      *pp = &((u8 *)pFd->pMapRegion)[iOff];
--      pFd->nFetchOut++;
-+  assert( pFile );
-+  assert( pSem );
-+  OSTRACE(("UNLOCK  %d %d was %d pid=%d (sem)\n", pFile->h, eFileLock,
-+           pFile->eFileLock, getpid()));
-+  assert( eFileLock<=SHARED_LOCK );
-+  
-+  /* no-op if possible */
-+  if( pFile->eFileLock==eFileLock ){
-+    return SQLITE_OK;
-+  }
-+  
-+  /* shared can just be set because we always have an exclusive */
-+  if (eFileLock==SHARED_LOCK) {
-+    pFile->eFileLock = eFileLock;
-+    return SQLITE_OK;
-+  }
-+  
-+  /* no, really unlock. */
-+  if ( sem_post(pSem)==-1 ) {
-+    int rc, tErrno = errno;
-+    rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
-+    if( IS_LOCK_ERROR(rc) ){
-+      pFile->lastErrno = tErrno;
-     }
-+    return rc; 
-   }
--#endif
-+  pFile->eFileLock = NO_LOCK;
-   return SQLITE_OK;
- }
- 
- /*
--** If the third argument is non-NULL, then this function releases a 
--** reference obtained by an earlier call to unixFetch(). The second
--** argument passed to this function must be the same as the corresponding
--** argument that was passed to the unixFetch() 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 unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){
--  unixFile *pFd = (unixFile *)fd;   /* The underlying database file */
--  UNUSED_PARAMETER(iOff);
--
--  /* 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] );
--
--  if( p ){
--    pFd->nFetchOut--;
--  }else{
--    unixUnmapfile(pFd);
-+ ** Close a file.
-+ */
-+static int semClose(sqlite3_file *id) {
-+  if( id ){
-+    unixFile *pFile = (unixFile*)id;
-+    semUnlock(id, NO_LOCK);
-+    assert( pFile );
-+    unixEnterMutex();
-+    releaseInodeInfo(pFile);
-+    unixLeaveMutex();
-+    closeUnixFile(id);
-   }
--
--  assert( pFd->nFetchOut>=0 );
-   return SQLITE_OK;
- }
- 
-+#endif /* OS_VXWORKS */
- /*
--** Here ends the implementation of all sqlite3_file methods.
-+** Named semaphore locking is only available on VxWorks.
- **
--********************** End sqlite3_file Methods *******************************
-+*************** End of the named semaphore lock implementation ****************
- ******************************************************************************/
- 
--/*
--** This division contains definitions of sqlite3_io_methods objects that
--** implement various file locking strategies.  It also contains definitions
--** of "finder" functions.  A finder-function is used to locate the appropriate
--** sqlite3_io_methods object for a particular database file.  The pAppData
--** field of the sqlite3_vfs VFS objects are initialized to be pointers to
--** the correct finder-function for that VFS.
--**
--** Most finder functions return a pointer to a fixed sqlite3_io_methods
--** object.  The only interesting finder-function is autolockIoFinder, which
--** looks at the filesystem type and tries to guess the best locking
--** strategy from that.
--**
--** For finder-funtion F, two objects are created:
--**
--**    (1) The real finder-function named "FImpt()".
--**
--**    (2) A constant pointer to this function named just "F".
--**
--**
--** A pointer to the F pointer is used as the pAppData value for VFS
--** objects.  We have to do this instead of letting pAppData point
--** directly at the finder-function since C90 rules prevent a void*
--** from be cast into a function pointer.
--**
--**
--** Each instance of this macro generates two objects:
-+
-+/******************************************************************************
-+*************************** Begin AFP Locking *********************************
- **
--**   *  A constant sqlite3_io_methods object call METHOD that has locking
--**      methods CLOSE, LOCK, UNLOCK, CKRESLOCK.
-+** AFP is the Apple Filing Protocol.  AFP is a network filesystem found
-+** on Apple Macintosh computers - both OS9 and OSX.
- **
--**   *  An I/O method finder function called FINDER that returns a pointer
--**      to the METHOD object in the previous bullet.
-+** Third-party implementations of AFP are available.  But this code here
-+** only works on OSX.
- */
--#define IOMETHODS(FINDER, METHOD, VERSION, CLOSE, LOCK, UNLOCK, CKLOCK)      \
--static const sqlite3_io_methods METHOD = {                                   \
--   VERSION,                    /* iVersion */                                \
--   CLOSE,                      /* xClose */                                  \
--   unixRead,                   /* xRead */                                   \
--   unixWrite,                  /* xWrite */                                  \
--   unixTruncate,               /* xTruncate */                               \
--   unixSync,                   /* xSync */                                   \
--   unixFileSize,               /* xFileSize */                               \
--   LOCK,                       /* xLock */                                   \
--   UNLOCK,                     /* xUnlock */                                 \
--   CKLOCK,                     /* xCheckReservedLock */                      \
--   unixFileControl,            /* xFileControl */                            \
--   unixSectorSize,             /* xSectorSize */                             \
--   unixDeviceCharacteristics,  /* xDeviceCapabilities */                     \
--   unixShmMap,                 /* xShmMap */                                 \
--   unixShmLock,                /* xShmLock */                                \
--   unixShmBarrier,             /* xShmBarrier */                             \
--   unixShmUnmap,               /* xShmUnmap */                               \
--   unixFetch,                  /* xFetch */                                  \
--   unixUnfetch,                /* xUnfetch */                                \
--};                                                                           \
--static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){   \
--  UNUSED_PARAMETER(z); UNUSED_PARAMETER(p);                                  \
--  return &METHOD;                                                            \
--}                                                                            \
--static const sqlite3_io_methods *(*const FINDER)(const char*,unixFile *p)    \
--    = FINDER##Impl;
- 
-+#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
- /*
--** Here are all of the sqlite3_io_methods objects for each of the
--** locking strategies.  Functions that return pointers to these methods
--** are also created.
-+** The afpLockingContext structure contains all afp lock specific state
- */
--IOMETHODS(
--  posixIoFinder,            /* Finder function name */
--  posixIoMethods,           /* sqlite3_io_methods object name */
--  3,                        /* shared memory and mmap are enabled */
--  unixClose,                /* xClose method */
--  unixLock,                 /* xLock method */
--  unixUnlock,               /* xUnlock method */
--  unixCheckReservedLock     /* xCheckReservedLock method */
--)
--IOMETHODS(
--  nolockIoFinder,           /* Finder function name */
--  nolockIoMethods,          /* sqlite3_io_methods object name */
--  1,                        /* shared memory is disabled */
--  nolockClose,              /* xClose method */
--  nolockLock,               /* xLock method */
--  nolockUnlock,             /* xUnlock method */
--  nolockCheckReservedLock   /* xCheckReservedLock method */
--)
--IOMETHODS(
--  dotlockIoFinder,          /* Finder function name */
--  dotlockIoMethods,         /* sqlite3_io_methods object name */
--  1,                        /* shared memory is disabled */
--  dotlockClose,             /* xClose method */
--  dotlockLock,              /* xLock method */
--  dotlockUnlock,            /* xUnlock method */
--  dotlockCheckReservedLock  /* xCheckReservedLock method */
--)
-+typedef struct afpLockingContext afpLockingContext;
-+struct afpLockingContext {
-+  int reserved;
-+  const char *dbPath;             /* Name of the open file */
-+};
- 
--#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
--IOMETHODS(
--  flockIoFinder,            /* Finder function name */
--  flockIoMethods,           /* sqlite3_io_methods object name */
--  1,                        /* shared memory is disabled */
--  flockClose,               /* xClose method */
--  flockLock,                /* xLock method */
--  flockUnlock,              /* xUnlock method */
--  flockCheckReservedLock    /* xCheckReservedLock method */
--)
--#endif
-+struct ByteRangeLockPB2
-+{
-+  unsigned long long offset;        /* offset to first byte to lock */
-+  unsigned long long length;        /* nbr of bytes to lock */
-+  unsigned long long retRangeStart; /* nbr of 1st byte locked if successful */
-+  unsigned char unLockFlag;         /* 1 = unlock, 0 = lock */
-+  unsigned char startEndFlag;       /* 1=rel to end of fork, 0=rel to start */
-+  int fd;                           /* file desc to assoc this lock with */
-+};
- 
--#if OS_VXWORKS
--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 */
--)
--#endif
-+#define afpfsByteRangeLock2FSCTL        _IOWR('z', 23, struct ByteRangeLockPB2)
- 
--#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
--IOMETHODS(
--  afpIoFinder,              /* Finder function name */
--  afpIoMethods,             /* sqlite3_io_methods object name */
--  1,                        /* shared memory is disabled */
--  afpClose,                 /* xClose method */
--  afpLock,                  /* xLock method */
--  afpUnlock,                /* xUnlock method */
--  afpCheckReservedLock      /* xCheckReservedLock method */
--)
--#endif
-+/*
-+** This is a utility for setting or clearing a bit-range lock on an
-+** AFP filesystem.
-+** 
-+** Return SQLITE_OK on success, SQLITE_BUSY on failure.
-+*/
-+static int afpSetLock(
-+  const char *path,              /* Name of the file to be locked or unlocked */
-+  unixFile *pFile,               /* Open file descriptor on path */
-+  unsigned long long offset,     /* First byte to be locked */
-+  unsigned long long length,     /* Number of bytes to lock */
-+  int setLockFlag                /* True to set lock.  False to clear lock */
-+){
-+  struct ByteRangeLockPB2 pb;
-+  int err;
-+  
-+  pb.unLockFlag = setLockFlag ? 0 : 1;
-+  pb.startEndFlag = 0;
-+  pb.offset = offset;
-+  pb.length = length; 
-+  pb.fd = pFile->h;
-+  
-+  OSTRACE(("AFPSETLOCK [%s] for %d%s in range %llx:%llx\n", 
-+    (setLockFlag?"ON":"OFF"), pFile->h, (pb.fd==-1?"[testval-1]":""),
-+    offset, length));
-+  err = fsctl(path, afpfsByteRangeLock2FSCTL, &pb, 0);
-+  if ( err==-1 ) {
-+    int rc;
-+    int tErrno = errno;
-+    OSTRACE(("AFPSETLOCK failed to fsctl() '%s' %d %s\n",
-+             path, tErrno, strerror(tErrno)));
-+#ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS
-+    rc = SQLITE_BUSY;
-+#else
-+    rc = sqliteErrorFromPosixError(tErrno,
-+                    setLockFlag ? SQLITE_IOERR_LOCK : SQLITE_IOERR_UNLOCK);
-+#endif /* SQLITE_IGNORE_AFP_LOCK_ERRORS */
-+    if( IS_LOCK_ERROR(rc) ){
-+      pFile->lastErrno = tErrno;
-+    }
-+    return rc;
-+  } else {
-+    return SQLITE_OK;
-+  }
-+}
- 
- /*
--** The proxy locking method is a "super-method" in the sense that it
--** opens secondary file descriptors for the conch and lock files and
--** it uses proxy, dot-file, AFP, and flock() locking methods on those
--** secondary files.  For this reason, the division that implements
--** proxy locking is located much further down in the file.  But we need
--** to go ahead and define the sqlite3_io_methods and finder function
--** for proxy locking here.  So we forward declare the I/O methods.
-+** 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, set *pResOut
-+** 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.
- */
--#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
--static int proxyClose(sqlite3_file*);
--static int proxyLock(sqlite3_file*, int);
--static int proxyUnlock(sqlite3_file*, int);
--static int proxyCheckReservedLock(sqlite3_file*, int*);
--IOMETHODS(
--  proxyIoFinder,            /* Finder function name */
--  proxyIoMethods,           /* sqlite3_io_methods object name */
--  1,                        /* shared memory is disabled */
--  proxyClose,               /* xClose method */
--  proxyLock,                /* xLock method */
--  proxyUnlock,              /* xUnlock method */
--  proxyCheckReservedLock    /* xCheckReservedLock method */
--)
--#endif
-+static int afpCheckReservedLock(sqlite3_file *id, int *pResOut){
-+  int rc = SQLITE_OK;
-+  int reserved = 0;
-+  unixFile *pFile = (unixFile*)id;
-+  afpLockingContext *context;
-+  
-+  SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
-+  
-+  assert( pFile );
-+  context = (afpLockingContext *) pFile->lockingContext;
-+  if( context->reserved ){
-+    *pResOut = 1;
-+    return SQLITE_OK;
-+  }
-+  unixEnterMutex(); /* Because pFile->pInode is shared across threads */
-+  
-+  /* Check if a thread in this process holds such a lock */
-+  if( pFile->pInode->eFileLock>SHARED_LOCK ){
-+    reserved = 1;
-+  }
-+  
-+  /* Otherwise see if some other process holds it.
-+   */
-+  if( !reserved ){
-+    /* lock the RESERVED byte */
-+    int lrc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1);  
-+    if( SQLITE_OK==lrc ){
-+      /* if we succeeded in taking the reserved lock, unlock it to restore
-+      ** the original state */
-+      lrc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1, 0);
-+    } else {
-+      /* if we failed to get the lock then someone else must have it */
-+      reserved = 1;
-+    }
-+    if( IS_LOCK_ERROR(lrc) ){
-+      rc=lrc;
-+    }
-+  }
-+  
-+  unixLeaveMutex();
-+  OSTRACE(("TEST WR-LOCK %d %d %d (afp)\n", pFile->h, rc, reserved));
-+  
-+  *pResOut = reserved;
-+  return rc;
-+}
- 
--/* nfs lockd on OSX 10.3+ doesn't clear write locks when a read lock is set */
--#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
--IOMETHODS(
--  nfsIoFinder,               /* Finder function name */
--  nfsIoMethods,              /* sqlite3_io_methods object name */
--  1,                         /* shared memory is disabled */
--  unixClose,                 /* xClose method */
--  unixLock,                  /* xLock method */
--  nfsUnlock,                 /* xUnlock method */
--  unixCheckReservedLock      /* xCheckReservedLock method */
--)
--#endif
-+/*
-+** Lock the file with the lock specified by parameter eFileLock - 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.  Use the sqlite3OsUnlock()
-+** routine to lower a locking level.
-+*/
-+static int afpLock(sqlite3_file *id, int eFileLock){
-+  int rc = SQLITE_OK;
-+  unixFile *pFile = (unixFile*)id;
-+  unixInodeInfo *pInode = pFile->pInode;
-+  afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
-+  
-+  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()));
-+
-+  /* 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
-+  ** unixEnterMutex() hasn't been called yet.
-+  */
-+  if( pFile->eFileLock>=eFileLock ){
-+    OSTRACE(("LOCK    %d %s ok (already held) (afp)\n", pFile->h,
-+           azFileLock(eFileLock)));
-+    return SQLITE_OK;
-+  }
-+
-+  /* Make sure the locking sequence is correct
-+  **  (1) We never move from unlocked to anything higher than shared lock.
-+  **  (2) SQLite never explicitly requests a pendig lock.
-+  **  (3) A shared lock is always held when a reserve lock is requested.
-+  */
-+  assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK );
-+  assert( eFileLock!=PENDING_LOCK );
-+  assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK );
-+  
-+  /* This mutex is needed because pFile->pInode is shared across threads
-+  */
-+  unixEnterMutex();
-+  pInode = pFile->pInode;
-+
-+  /* If some thread using this PID has a lock via a different unixFile*
-+  ** handle that precludes the requested lock, return BUSY.
-+  */
-+  if( (pFile->eFileLock!=pInode->eFileLock && 
-+       (pInode->eFileLock>=PENDING_LOCK || eFileLock>SHARED_LOCK))
-+     ){
-+    rc = SQLITE_BUSY;
-+    goto afp_end_lock;
-+  }
-+  
-+  /* If a SHARED lock is requested, and some thread using this PID already
-+  ** has a SHARED or RESERVED lock, then increment reference counts and
-+  ** return SQLITE_OK.
-+  */
-+  if( eFileLock==SHARED_LOCK && 
-+     (pInode->eFileLock==SHARED_LOCK || pInode->eFileLock==RESERVED_LOCK) ){
-+    assert( eFileLock==SHARED_LOCK );
-+    assert( pFile->eFileLock==0 );
-+    assert( pInode->nShared>0 );
-+    pFile->eFileLock = SHARED_LOCK;
-+    pInode->nShared++;
-+    pInode->nLock++;
-+    goto afp_end_lock;
-+  }
-+    
-+  /* A PENDING lock is needed before acquiring a SHARED lock and before
-+  ** acquiring an EXCLUSIVE lock.  For the SHARED lock, the PENDING will
-+  ** be released.
-+  */
-+  if( eFileLock==SHARED_LOCK 
-+      || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLock<PENDING_LOCK)
-+  ){
-+    int failed;
-+    failed = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 1);
-+    if (failed) {
-+      rc = failed;
-+      goto afp_end_lock;
-+    }
-+  }
-+  
-+  /* If control gets to this point, then actually go ahead and make
-+  ** operating system calls for the specified lock.
-+  */
-+  if( eFileLock==SHARED_LOCK ){
-+    int lrc1, lrc2, lrc1Errno = 0;
-+    long lk, mask;
-+    
-+    assert( pInode->nShared==0 );
-+    assert( pInode->eFileLock==0 );
-+        
-+    mask = (sizeof(long)==8) ? LARGEST_INT64 : 0x7fffffff;
-+    /* Now get the read-lock SHARED_LOCK */
-+    /* note that the quality of the randomness doesn't matter that much */
-+    lk = random(); 
-+    pInode->sharedByte = (lk & mask)%(SHARED_SIZE - 1);
-+    lrc1 = afpSetLock(context->dbPath, pFile, 
-+          SHARED_FIRST+pInode->sharedByte, 1, 1);
-+    if( IS_LOCK_ERROR(lrc1) ){
-+      lrc1Errno = pFile->lastErrno;
-+    }
-+    /* Drop the temporary PENDING lock */
-+    lrc2 = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0);
-+    
-+    if( IS_LOCK_ERROR(lrc1) ) {
-+      pFile->lastErrno = lrc1Errno;
-+      rc = lrc1;
-+      goto afp_end_lock;
-+    } else if( IS_LOCK_ERROR(lrc2) ){
-+      rc = lrc2;
-+      goto afp_end_lock;
-+    } else if( lrc1 != SQLITE_OK ) {
-+      rc = lrc1;
-+    } else {
-+      pFile->eFileLock = SHARED_LOCK;
-+      pInode->nLock++;
-+      pInode->nShared = 1;
-+    }
-+  }else if( eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1 ){
-+    /* We are trying for an exclusive lock but another thread in this
-+     ** same process is still holding a shared lock. */
-+    rc = SQLITE_BUSY;
-+  }else{
-+    /* The request was for a RESERVED or EXCLUSIVE lock.  It is
-+    ** assumed that there is a SHARED or greater lock on the file
-+    ** already.
-+    */
-+    int failed = 0;
-+    assert( 0!=pFile->eFileLock );
-+    if (eFileLock >= RESERVED_LOCK && pFile->eFileLock < RESERVED_LOCK) {
-+        /* Acquire a RESERVED lock */
-+        failed = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1);
-+      if( !failed ){
-+        context->reserved = 1;
-+      }
-+    }
-+    if (!failed && eFileLock == EXCLUSIVE_LOCK) {
-+      /* Acquire an EXCLUSIVE lock */
-+        
-+      /* Remove the shared lock before trying the range.  we'll need to 
-+      ** reestablish the shared lock if we can't get the  afpUnlock
-+      */
-+      if( !(failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST +
-+                         pInode->sharedByte, 1, 0)) ){
-+        int failed2 = SQLITE_OK;
-+        /* now attemmpt to get the exclusive lock range */
-+        failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST, 
-+                               SHARED_SIZE, 1);
-+        if( failed && (failed2 = afpSetLock(context->dbPath, pFile, 
-+                       SHARED_FIRST + pInode->sharedByte, 1, 1)) ){
-+          /* Can't reestablish the shared lock.  Sqlite can't deal, this is
-+          ** a critical I/O error
-+          */
-+          rc = ((failed & SQLITE_IOERR) == SQLITE_IOERR) ? failed2 : 
-+               SQLITE_IOERR_LOCK;
-+          goto afp_end_lock;
-+        } 
-+      }else{
-+        rc = failed; 
-+      }
-+    }
-+    if( failed ){
-+      rc = failed;
-+    }
-+  }
-+  
-+  if( rc==SQLITE_OK ){
-+    pFile->eFileLock = eFileLock;
-+    pInode->eFileLock = eFileLock;
-+  }else if( eFileLock==EXCLUSIVE_LOCK ){
-+    pFile->eFileLock = PENDING_LOCK;
-+    pInode->eFileLock = PENDING_LOCK;
-+  }
-+  
-+afp_end_lock:
-+  unixLeaveMutex();
-+  OSTRACE(("LOCK    %d %s %s (afp)\n", pFile->h, azFileLock(eFileLock), 
-+         rc==SQLITE_OK ? "ok" : "failed"));
-+  return rc;
-+}
- 
--#if defined(__APPLE__) && 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.
-+/*
-+** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
-+** must be either NO_LOCK or SHARED_LOCK.
- **
--** This is for MacOSX only.
-+** If the locking level of the file descriptor is already at or below
-+** the requested locking level, this routine is a no-op.
- */
--static const sqlite3_io_methods *autolockIoFinderImpl(
--  const char *filePath,    /* name of the database file */
--  unixFile *pNew           /* open file object for the database file */
--){
--  static const struct Mapping {
--    const char *zFilesystem;              /* Filesystem type name */
--    const sqlite3_io_methods *pMethods;   /* Appropriate locking method */
--  } aMap[] = {
--    { "hfs",    &posixIoMethods },
--    { "ufs",    &posixIoMethods },
--    { "afpfs",  &afpIoMethods },
--    { "smbfs",  &afpIoMethods },
--    { "webdav", &nolockIoMethods },
--    { 0, 0 }
--  };
--  int i;
--  struct statfs fsInfo;
--  struct flock lockInfo;
-+static int afpUnlock(sqlite3_file *id, int eFileLock) {
-+  int rc = SQLITE_OK;
-+  unixFile *pFile = (unixFile*)id;
-+  unixInodeInfo *pInode;
-+  afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
-+  int skipShared = 0;
-+#ifdef SQLITE_TEST
-+  int h = pFile->h;
-+#endif
- 
--  if( !filePath ){
--    /* If filePath==NULL that means we are dealing with a transient file
--    ** that does not need to be locked. */
--    return &nolockIoMethods;
-+  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()));
-+
-+  assert( eFileLock<=SHARED_LOCK );
-+  if( pFile->eFileLock<=eFileLock ){
-+    return SQLITE_OK;
-   }
--  if( statfs(filePath, &fsInfo) != -1 ){
--    if( fsInfo.f_flags & MNT_RDONLY ){
--      return &nolockIoMethods;
-+  unixEnterMutex();
-+  pInode = pFile->pInode;
-+  assert( pInode->nShared!=0 );
-+  if( pFile->eFileLock>SHARED_LOCK ){
-+    assert( pInode->eFileLock==pFile->eFileLock );
-+    SimulateIOErrorBenign(1);
-+    SimulateIOError( h=(-1) )
-+    SimulateIOErrorBenign(0);
-+    
-+#ifdef SQLITE_DEBUG
-+    /* When reducing a lock such that other processes can start
-+    ** reading the database file again, make sure that the
-+    ** transaction counter was updated if any part of the database
-+    ** file changed.  If the transaction counter is not updated,
-+    ** other connections to the same file might not realize that
-+    ** the file has changed and hence might not know to flush their
-+    ** cache.  The use of a stale cache can lead to database corruption.
-+    */
-+    assert( pFile->inNormalWrite==0
-+           || pFile->dbUpdate==0
-+           || pFile->transCntrChng==1 );
-+    pFile->inNormalWrite = 0;
-+#endif
-+    
-+    if( pFile->eFileLock==EXCLUSIVE_LOCK ){
-+      rc = afpSetLock(context->dbPath, pFile, SHARED_FIRST, SHARED_SIZE, 0);
-+      if( rc==SQLITE_OK && (eFileLock==SHARED_LOCK || pInode->nShared>1) ){
-+        /* only re-establish the shared lock if necessary */
-+        int sharedLockByte = SHARED_FIRST+pInode->sharedByte;
-+        rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 1);
-+      } else {
-+        skipShared = 1;
-+      }
-     }
--    for(i=0; aMap[i].zFilesystem; i++){
--      if( strcmp(fsInfo.f_fstypename, aMap[i].zFilesystem)==0 ){
--        return aMap[i].pMethods;
-+    if( rc==SQLITE_OK && pFile->eFileLock>=PENDING_LOCK ){
-+      rc = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0);
-+    } 
-+    if( rc==SQLITE_OK && pFile->eFileLock>=RESERVED_LOCK && context->reserved ){
-+      rc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1, 0);
-+      if( !rc ){ 
-+        context->reserved = 0; 
-       }
-     }
-+    if( rc==SQLITE_OK && (eFileLock==SHARED_LOCK || pInode->nShared>1)){
-+      pInode->eFileLock = SHARED_LOCK;
-+    }
-   }
-+  if( rc==SQLITE_OK && eFileLock==NO_LOCK ){
- 
--  /* Default case. Handles, amongst others, "nfs".
--  ** Test byte-range lock using fcntl(). If the call succeeds, 
--  ** assume that the file-system supports POSIX style locks. 
--  */
--  lockInfo.l_len = 1;
--  lockInfo.l_start = 0;
--  lockInfo.l_whence = SEEK_SET;
--  lockInfo.l_type = F_RDLCK;
--  if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) {
--    if( strcmp(fsInfo.f_fstypename, "nfs")==0 ){
--      return &nfsIoMethods;
--    } else {
--      return &posixIoMethods;
-+    /* Decrement the shared lock counter.  Release the lock using an
-+    ** OS call only when all threads in this same process have released
-+    ** the lock.
-+    */
-+    unsigned long long sharedLockByte = SHARED_FIRST+pInode->sharedByte;
-+    pInode->nShared--;
-+    if( pInode->nShared==0 ){
-+      SimulateIOErrorBenign(1);
-+      SimulateIOError( h=(-1) )
-+      SimulateIOErrorBenign(0);
-+      if( !skipShared ){
-+        rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 0);
-+      }
-+      if( !rc ){
-+        pInode->eFileLock = NO_LOCK;
-+        pFile->eFileLock = NO_LOCK;
-+      }
-+    }
-+    if( rc==SQLITE_OK ){
-+      pInode->nLock--;
-+      assert( pInode->nLock>=0 );
-+      if( pInode->nLock==0 ){
-+        closePendingFds(pFile);
-+      }
-     }
--  }else{
--    return &dotlockIoMethods;
-   }
-+  
-+  unixLeaveMutex();
-+  if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock;
-+  return rc;
- }
--static const sqlite3_io_methods 
--  *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl;
--
--#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.
-+/*
-+** Close a file & cleanup AFP specific locking context 
- */
--static const sqlite3_io_methods *autolockIoFinderImpl(
--  const char *filePath,    /* name of the database file */
--  unixFile *pNew           /* the open file object */
--){
--  struct flock lockInfo;
--
--  if( !filePath ){
--    /* If filePath==NULL that means we are dealing with a transient file
--    ** that does not need to be locked. */
--    return &nolockIoMethods;
--  }
--
--  /* Test if fcntl() is supported and use POSIX style locks.
--  ** Otherwise fall back to the named semaphore method.
--  */
--  lockInfo.l_len = 1;
--  lockInfo.l_start = 0;
--  lockInfo.l_whence = SEEK_SET;
--  lockInfo.l_type = F_RDLCK;
--  if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) {
--    return &posixIoMethods;
--  }else{
--    return &semIoMethods;
-+static int afpClose(sqlite3_file *id) {
-+  int rc = SQLITE_OK;
-+  if( id ){
-+    unixFile *pFile = (unixFile*)id;
-+    afpUnlock(id, NO_LOCK);
-+    unixEnterMutex();
-+    if( pFile->pInode && pFile->pInode->nLock ){
-+      /* If there are outstanding locks, do not actually close the file just
-+      ** yet because that would clear those locks.  Instead, add the file
-+      ** descriptor to pInode->aPending.  It will be automatically closed when
-+      ** the last lock is cleared.
-+      */
-+      setPendingFd(pFile);
-+    }
-+    releaseInodeInfo(pFile);
-+    sqlite3_free(pFile->lockingContext);
-+    rc = closeUnixFile(id);
-+    unixLeaveMutex();
-   }
-+  return rc;
- }
--static const sqlite3_io_methods 
--  *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl;
- 
--#endif /* OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE */
-+#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
-+/*
-+** The code above is the AFP lock implementation.  The code is specific
-+** to MacOSX and does not work on other unix platforms.  No alternative
-+** is available.  If you don't compile for a mac, then the "unix-afp"
-+** VFS is not available.
-+**
-+********************* End of the AFP lock implementation **********************
-+******************************************************************************/
-+
-+/******************************************************************************
-+*************************** Begin NFS Locking ********************************/
- 
-+#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
- /*
--** An abstract type for a pointer to a IO method finder function:
--*/
--typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*);
-+ ** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
-+ ** 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.
-+ */
-+static int nfsUnlock(sqlite3_file *id, int eFileLock){
-+  return posixUnlock(id, eFileLock, 1);
-+}
- 
-+#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
-+/*
-+** The code above is the NFS lock implementation.  The code is specific
-+** to MacOSX and does not work on other unix platforms.  No alternative
-+** is available.  
-+**
-+********************* End of the NFS lock implementation **********************
-+******************************************************************************/
- 
--/****************************************************************************
--**************************** sqlite3_vfs methods ****************************
-+/******************************************************************************
-+**************** Non-locking sqlite3_file methods *****************************
- **
--** This division contains the implementation of methods on the
--** sqlite3_vfs object.
-+** The next division contains implementations for all methods of the 
-+** sqlite3_file object other than the locking methods.  The locking
-+** methods were defined in divisions above (one locking method per
-+** division).  Those methods that are common to all locking modes
-+** are gather together into this division.
- */
- 
- /*
--** Initialize the contents of the unixFile structure pointed to by pId.
-+** Seek to the offset passed as the second argument, then read cnt 
-+** bytes into pBuf. Return the number of bytes actually read.
-+**
-+** 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.
-+** See tickets #2741 and #2681.
-+**
-+** To avoid stomping the errno value on a failed read the lastErrno value
-+** is set before returning.
- */
--static int fillInUnixFile(
--  sqlite3_vfs *pVfs,      /* Pointer to vfs object */
--  int h,                  /* Open file descriptor of file being opened */
--  sqlite3_file *pId,      /* Write to the unixFile structure here */
--  const char *zFilename,  /* Name of the file being opened */
--  int ctrlFlags           /* Zero or more UNIXFILE_* values */
--){
--  const sqlite3_io_methods *pLockingStyle;
--  unixFile *pNew = (unixFile *)pId;
--  int rc = SQLITE_OK;
--
--  assert( pNew->pInode==NULL );
--
--  /* Usually the path zFilename should not be a relative pathname. The
--  ** exception is when opening the proxy "conch" file in builds that
--  ** include the special Apple locking styles.
--  */
--#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
--  assert( zFilename==0 || zFilename[0]=='/' 
--    || pVfs->pAppData==(void*)&autolockIoFinder );
-+static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
-+  int got;
-+  int prior = 0;
-+#if (!defined(USE_PREAD) && !defined(USE_PREAD64))
-+  i64 newOffset;
-+#endif
-+  TIMER_START;
-+  assert( cnt==(cnt&0x1ffff) );
-+  cnt &= 0x1ffff;
-+  do{
-+#if defined(USE_PREAD)
-+    got = osPread(id->h, pBuf, cnt, offset);
-+    SimulateIOError( got = -1 );
-+#elif defined(USE_PREAD64)
-+    got = osPread64(id->h, pBuf, cnt, offset);
-+    SimulateIOError( got = -1 );
- #else
--  assert( zFilename==0 || zFilename[0]=='/' );
-+    newOffset = lseek(id->h, offset, SEEK_SET);
-+    SimulateIOError( newOffset-- );
-+    if( newOffset!=offset ){
-+      if( newOffset == -1 ){
-+        ((unixFile*)id)->lastErrno = errno;
-+      }else{
-+        ((unixFile*)id)->lastErrno = 0;
-+      }
-+      return -1;
-+    }
-+    got = osRead(id->h, pBuf, cnt);
- #endif
-+    if( got==cnt ) break;
-+    if( got<0 ){
-+      if( errno==EINTR ){ got = 1; continue; }
-+      prior = 0;
-+      ((unixFile*)id)->lastErrno = errno;
-+      break;
-+    }else if( got>0 ){
-+      cnt -= got;
-+      offset += got;
-+      prior += got;
-+      pBuf = (void*)(got + (char*)pBuf);
-+    }
-+  }while( got>0 );
-+  TIMER_END;
-+  OSTRACE(("READ    %-3d %5d %7lld %llu\n",
-+            id->h, got+prior, offset-prior, TIMER_ELAPSED));
-+  return got+prior;
-+}
- 
--  /* No locking occurs in temporary files */
--  assert( zFilename!=0 || (ctrlFlags & UNIXFILE_NOLOCK)!=0 );
-+/*
-+** Read data from a file into a buffer.  Return SQLITE_OK if all
-+** bytes were read successfully and SQLITE_IOERR if anything goes
-+** wrong.
-+*/
-+static int unixRead(
-+  sqlite3_file *id, 
-+  void *pBuf, 
-+  int amt,
-+  sqlite3_int64 offset
-+){
-+  unixFile *pFile = (unixFile *)id;
-+  int got;
-+  assert( id );
-+  assert( offset>=0 );
-+  assert( amt>0 );
- 
--  OSTRACE(("OPEN    %-3d %s\n", h, zFilename));
--  pNew->h = h;
--  pNew->pVfs = pVfs;
--  pNew->zPath = zFilename;
--  pNew->ctrlFlags = (u8)ctrlFlags;
--  pNew->mmapSizeMax = sqlite3GlobalConfig.szMmap;
--  if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0),
--                           "psow", SQLITE_POWERSAFE_OVERWRITE) ){
--    pNew->ctrlFlags |= UNIXFILE_PSOW;
--  }
--  if( strcmp(pVfs->zName,"unix-excl")==0 ){
--    pNew->ctrlFlags |= UNIXFILE_EXCL;
--  }
-+  /* If this is a database file (not a journal, master-journal or temp
-+  ** file), the bytes in the locking range should never be read or written. */
-+#if 0
-+  assert( pFile->pUnused==0
-+       || offset>=PENDING_BYTE+512
-+       || offset+amt<=PENDING_BYTE 
-+  );
-+#endif
- 
--#if OS_VXWORKS
--  pNew->pId = vxworksFindFileId(zFilename);
--  if( pNew->pId==0 ){
--    ctrlFlags |= UNIXFILE_NOLOCK;
--    rc = SQLITE_NOMEM;
-+#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);
-+      return SQLITE_OK;
-+    }else{
-+      int nCopy = pFile->mmapSize - offset;
-+      memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy);
-+      pBuf = &((u8 *)pBuf)[nCopy];
-+      amt -= nCopy;
-+      offset += nCopy;
-+    }
-   }
- #endif
- 
--  if( ctrlFlags & UNIXFILE_NOLOCK ){
--    pLockingStyle = &nolockIoMethods;
-+  got = seekAndRead(pFile, offset, pBuf, amt);
-+  if( got==amt ){
-+    return SQLITE_OK;
-+  }else if( got<0 ){
-+    /* lastErrno set by seekAndRead */
-+    return SQLITE_IOERR_READ;
-   }else{
--    pLockingStyle = (**(finder_type*)pVfs->pAppData)(zFilename, pNew);
--#if SQLITE_ENABLE_LOCKING_STYLE
--    /* Cache zFilename in the locking context (AFP and dotlock override) for
--    ** proxyLock activation is possible (remote proxy is based on db name)
--    ** zFilename remains valid until file is closed, to support */
--    pNew->lockingContext = (void*)zFilename;
--#endif
-+    pFile->lastErrno = 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;
-   }
-+}
- 
--  if( pLockingStyle == &posixIoMethods
--#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
--    || pLockingStyle == &nfsIoMethods
--#endif
--  ){
--    unixEnterMutex();
--    rc = findInodeInfo(pNew, &pNew->pInode);
--    if( rc!=SQLITE_OK ){
--      /* If an error occurred in findInodeInfo(), close the file descriptor
--      ** immediately, before releasing the mutex. findInodeInfo() may fail
--      ** in two scenarios:
--      **
--      **   (a) A call to fstat() failed.
--      **   (b) A malloc failed.
--      **
--      ** Scenario (b) may only occur if the process is holding no other
--      ** file descriptors open on the same file. If there were other file
--      ** descriptors on this file, then no malloc would be required by
--      ** findInodeInfo(). If this is the case, it is quite safe to close
--      ** handle h - as it is guaranteed that no posix locks will be released
--      ** by doing so.
--      **
--      ** If scenario (a) caused the error then things are not so safe. The
--      ** implicit assumption here is that if fstat() fails, things are in
--      ** such bad shape that dropping a lock or two doesn't matter much.
--      */
--      robust_close(pNew, h, __LINE__);
--      h = -1;
-+/*
-+** Attempt to seek the file-descriptor passed as the first argument to
-+** absolute offset iOff, then attempt to write nBuf bytes of data from
-+** pBuf to it. If an error occurs, return -1 and set *piErrno. Otherwise, 
-+** return the actual number of bytes written (which may be less than
-+** nBuf).
-+*/
-+static int seekAndWriteFd(
-+  int fd,                         /* File descriptor to write to */
-+  i64 iOff,                       /* File offset to begin writing at */
-+  const void *pBuf,               /* Copy data from this buffer to the file */
-+  int nBuf,                       /* Size of buffer pBuf in bytes */
-+  int *piErrno                    /* OUT: Error number if error occurs */
-+){
-+  int rc = 0;                     /* Value returned by system call */
-+
-+  assert( nBuf==(nBuf&0x1ffff) );
-+  nBuf &= 0x1ffff;
-+  TIMER_START;
-+
-+#if defined(USE_PREAD)
-+  do{ rc = 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);
-+#else
-+  do{
-+    i64 iSeek = lseek(fd, iOff, SEEK_SET);
-+    SimulateIOError( iSeek-- );
-+
-+    if( iSeek!=iOff ){
-+      if( piErrno ) *piErrno = (iSeek==-1 ? errno : 0);
-+      return -1;
-     }
--    unixLeaveMutex();
--  }
-+    rc = osWrite(fd, pBuf, nBuf);
-+  }while( rc<0 && errno==EINTR );
-+#endif
-+
-+  TIMER_END;
-+  OSTRACE(("WRITE   %-3d %5d %7lld %llu\n", fd, rc, iOff, TIMER_ELAPSED));
-+
-+  if( rc<0 && piErrno ) *piErrno = errno;
-+  return rc;
-+}
-+
-+
-+/*
-+** Seek to the offset in id->offset then read cnt bytes into pBuf.
-+** Return the number of bytes actually read.  Update the offset.
-+**
-+** To avoid stomping the errno value on a failed write the lastErrno value
-+** is set before returning.
-+*/
-+static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){
-+  return seekAndWriteFd(id->h, offset, pBuf, cnt, &id->lastErrno);
-+}
-+
-+
-+/*
-+** Write data from a buffer into a file.  Return SQLITE_OK on success
-+** or some other error code on failure.
-+*/
-+static int unixWrite(
-+  sqlite3_file *id, 
-+  const void *pBuf, 
-+  int amt,
-+  sqlite3_int64 offset 
-+){
-+  unixFile *pFile = (unixFile*)id;
-+  int wrote = 0;
-+  assert( id );
-+  assert( amt>0 );
-+
-+  /* If this is a database file (not a journal, master-journal or temp
-+  ** file), the bytes in the locking range should never be read or written. */
-+#if 0
-+  assert( pFile->pUnused==0
-+       || offset>=PENDING_BYTE+512
-+       || offset+amt<=PENDING_BYTE 
-+  );
-+#endif
- 
--#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
--  else if( pLockingStyle == &afpIoMethods ){
--    /* AFP locking uses the file path so it needs to be included in
--    ** the afpLockingContext.
--    */
--    afpLockingContext *pCtx;
--    pNew->lockingContext = pCtx = sqlite3_malloc( sizeof(*pCtx) );
--    if( pCtx==0 ){
--      rc = SQLITE_NOMEM;
--    }else{
--      /* NB: zFilename exists and remains valid until the file is closed
--      ** according to requirement F11141.  So we do not need to make a
--      ** copy of the filename. */
--      pCtx->dbPath = zFilename;
--      pCtx->reserved = 0;
--      srandomdev();
--      unixEnterMutex();
--      rc = findInodeInfo(pNew, &pNew->pInode);
--      if( rc!=SQLITE_OK ){
--        sqlite3_free(pNew->lockingContext);
--        robust_close(pNew, h, __LINE__);
--        h = -1;
-+#ifdef SQLITE_DEBUG
-+  /* If we are doing a normal write to a database file (as opposed to
-+  ** doing a hot-journal rollback or a write to some file other than a
-+  ** normal database file) then record the fact that the database
-+  ** has changed.  If the transaction counter is modified, record that
-+  ** fact too.
-+  */
-+  if( pFile->inNormalWrite ){
-+    pFile->dbUpdate = 1;  /* The database has been modified */
-+    if( offset<=24 && offset+amt>=27 ){
-+      int rc;
-+      char oldCntr[4];
-+      SimulateIOErrorBenign(1);
-+      rc = seekAndRead(pFile, 24, oldCntr, 4);
-+      SimulateIOErrorBenign(0);
-+      if( rc!=4 || memcmp(oldCntr, &((char*)pBuf)[24-offset], 4)!=0 ){
-+        pFile->transCntrChng = 1;  /* The transaction counter has changed */
-       }
--      unixLeaveMutex();        
-     }
-   }
- #endif
- 
--  else if( pLockingStyle == &dotlockIoMethods ){
--    /* Dotfile locking uses the file path so it needs to be included in
--    ** the dotlockLockingContext 
--    */
--    char *zLockFile;
--    int nFilename;
--    assert( zFilename!=0 );
--    nFilename = (int)strlen(zFilename) + 6;
--    zLockFile = (char *)sqlite3_malloc(nFilename);
--    if( zLockFile==0 ){
--      rc = SQLITE_NOMEM;
-+#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);
-+      return SQLITE_OK;
-     }else{
--      sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename);
-+      int nCopy = pFile->mmapSize - offset;
-+      memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy);
-+      pBuf = &((u8 *)pBuf)[nCopy];
-+      amt -= nCopy;
-+      offset += nCopy;
-     }
--    pNew->lockingContext = zLockFile;
-   }
-+#endif
- 
--#if OS_VXWORKS
--  else if( pLockingStyle == &semIoMethods ){
--    /* Named semaphore locking uses the file path so it needs to be
--    ** included in the semLockingContext
--    */
--    unixEnterMutex();
--    rc = findInodeInfo(pNew, &pNew->pInode);
--    if( (rc==SQLITE_OK) && (pNew->pInode->pSem==NULL) ){
--      char *zSemName = pNew->pInode->aSemName;
--      int n;
--      sqlite3_snprintf(MAX_PATHNAME, zSemName, "/%s.sem",
--                       pNew->pId->zCanonicalName);
--      for( n=1; zSemName[n]; n++ )
--        if( zSemName[n]=='/' ) zSemName[n] = '_';
--      pNew->pInode->pSem = sem_open(zSemName, O_CREAT, 0666, 1);
--      if( pNew->pInode->pSem == SEM_FAILED ){
--        rc = SQLITE_NOMEM;
--        pNew->pInode->aSemName[0] = '\0';
--      }
-+  while( amt>0 && (wrote = seekAndWrite(pFile, offset, pBuf, amt))>0 ){
-+    amt -= wrote;
-+    offset += wrote;
-+    pBuf = &((char*)pBuf)[wrote];
-+  }
-+  SimulateIOError(( wrote=(-1), amt=1 ));
-+  SimulateDiskfullError(( wrote=0, amt=1 ));
-+
-+  if( amt>0 ){
-+    if( wrote<0 && pFile->lastErrno!=ENOSPC ){
-+      /* lastErrno set by seekAndWrite */
-+      return SQLITE_IOERR_WRITE;
-+    }else{
-+      pFile->lastErrno = 0; /* not a system error */
-+      return SQLITE_FULL;
-     }
--    unixLeaveMutex();
-   }
-+
-+  return SQLITE_OK;
-+}
-+
-+#ifdef SQLITE_TEST
-+/*
-+** Count the number of fullsyncs and normal syncs.  This is used to test
-+** that syncs and fullsyncs are occurring at the right times.
-+*/
-+SQLITE_API int sqlite3_sync_count = 0;
-+SQLITE_API int sqlite3_fullsync_count = 0;
- #endif
--  
--  pNew->lastErrno = 0;
--#if OS_VXWORKS
--  if( rc!=SQLITE_OK ){
--    if( h>=0 ) robust_close(pNew, h, __LINE__);
--    h = -1;
--    osUnlink(zFilename);
--    pNew->ctrlFlags |= UNIXFILE_DELETE;
--  }
-+
-+/*
-+** 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
-+*/
-+#if !defined(fdatasync)
-+# define fdatasync fsync
- #endif
--  if( rc!=SQLITE_OK ){
--    if( h>=0 ) robust_close(pNew, h, __LINE__);
--  }else{
--    pNew->pMethod = pLockingStyle;
--    OpenCounter(+1);
--    verifyDbFile(pNew);
--  }
--  return rc;
--}
- 
- /*
--** Return the name of a directory in which to put temporary files.
--** If no suitable temporary file directory can be found, return NULL.
-+** Define HAVE_FULLFSYNC to 0 or 1 depending on whether or not
-+** the F_FULLFSYNC macro is defined.  F_FULLFSYNC is currently
-+** only available on Mac OS X.  But that could change.
- */
--static const char *unixTempFileDir(void){
--  static const char *azDirs[] = {
--     0,
--     0,
--     "/var/tmp",
--     "/usr/tmp",
--     "/tmp",
--     0        /* List terminator */
--  };
--  unsigned int i;
--  struct stat buf;
--  const char *zDir = 0;
-+#ifdef F_FULLFSYNC
-+# define HAVE_FULLFSYNC 1
-+#else
-+# define HAVE_FULLFSYNC 0
-+#endif
- 
--  azDirs[0] = sqlite3_temp_directory;
--  if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
--  for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
--    if( zDir==0 ) continue;
--    if( osStat(zDir, &buf) ) continue;
--    if( !S_ISDIR(buf.st_mode) ) continue;
--    if( osAccess(zDir, 07) ) continue;
--    break;
--  }
--  return zDir;
--}
- 
- /*
--** Create a temporary file name in zBuf.  zBuf must be allocated
--** by the calling process and must be big enough to hold at least
--** pVfs->mxPathname bytes.
-+** The fsync() system call does not work as advertised on many
-+** unix systems.  The following procedure is an attempt to make
-+** it work better.
-+**
-+** The SQLITE_NO_SYNC macro disables all fsync()s.  This is useful
-+** for testing when we want to run through the test suite quickly.
-+** You are strongly advised *not* to deploy with SQLITE_NO_SYNC
-+** enabled, however, since with SQLITE_NO_SYNC enabled, an OS crash
-+** or power failure will likely corrupt the database file.
-+**
-+** SQLite sets the dataOnly flag if the size of the file is unchanged.
-+** The idea behind dataOnly is that it should only write the file content
-+** to disk, not the inode.  We only set dataOnly if the file size is 
-+** unchanged since the file size is part of the inode.  However, 
-+** Ted Ts'o tells us that fdatasync() will also write the inode if the
-+** file size has changed.  The only real difference between fdatasync()
-+** and fsync(), Ted tells us, is that fdatasync() will not flush the
-+** inode if the mtime or owner or other inode attributes have changed.
-+** We only care about the file size, not the other file attributes, so
-+** as far as SQLite is concerned, an fdatasync() is always adequate.
-+** So, we always use fdatasync() if it is available, regardless of
-+** the value of the dataOnly flag.
- */
--static int unixGetTempname(int nBuf, char *zBuf){
--  static const unsigned char zChars[] =
--    "abcdefghijklmnopqrstuvwxyz"
--    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
--    "0123456789";
--  unsigned int i, j;
--  const char *zDir;
-+static int full_fsync(int fd, int fullSync, int dataOnly){
-+  int rc;
- 
--  /* 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. 
-+  /* The following "ifdef/elif/else/" block has the same structure as
-+  ** the one below. It is replicated here solely to avoid cluttering 
-+  ** up the real code with the UNUSED_PARAMETER() macros.
-   */
--  SimulateIOError( return SQLITE_IOERR );
-+#ifdef SQLITE_NO_SYNC
-+  UNUSED_PARAMETER(fd);
-+  UNUSED_PARAMETER(fullSync);
-+  UNUSED_PARAMETER(dataOnly);
-+#elif HAVE_FULLFSYNC
-+  UNUSED_PARAMETER(dataOnly);
-+#else
-+  UNUSED_PARAMETER(fullSync);
-+  UNUSED_PARAMETER(dataOnly);
-+#endif
- 
--  zDir = unixTempFileDir();
--  if( zDir==0 ) zDir = ".";
-+  /* Record the number of times that we do a normal fsync() and 
-+  ** FULLSYNC.  This is used during testing to verify that this procedure
-+  ** gets called with the correct arguments.
-+  */
-+#ifdef SQLITE_TEST
-+  if( fullSync ) sqlite3_fullsync_count++;
-+  sqlite3_sync_count++;
-+#endif
- 
--  /* Check that the output buffer is large enough for the temporary file 
--  ** name. If it is not, return SQLITE_ERROR.
-+  /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
-+  ** no-op
-   */
--  if( (strlen(zDir) + strlen(SQLITE_TEMP_FILE_PREFIX) + 18) >= (size_t)nBuf ){
--    return SQLITE_ERROR;
-+#ifdef SQLITE_NO_SYNC
-+  rc = SQLITE_OK;
-+#elif HAVE_FULLFSYNC
-+  if( fullSync ){
-+    rc = osFcntl(fd, F_FULLFSYNC, 0);
-+  }else{
-+    rc = 1;
-+  }
-+  /* If the FULLFSYNC failed, fall back to attempting an fsync().
-+  ** It shouldn't be possible for fullfsync to fail on the local 
-+  ** file system (on OSX), so failure indicates that FULLFSYNC
-+  ** isn't supported for this file system. So, attempt an fsync 
-+  ** and (for now) ignore the overhead of a superfluous fcntl call.  
-+  ** It'd be better to detect fullfsync support once and avoid 
-+  ** the fcntl call every time sync is called.
-+  */
-+  if( rc ) rc = fsync(fd);
-+
-+#elif defined(__APPLE__)
-+  /* fdatasync() on HFS+ doesn't yet flush the file size if it changed correctly
-+  ** so currently we default to the macro that redefines fdatasync to fsync
-+  */
-+  rc = fsync(fd);
-+#else 
-+  rc = fdatasync(fd);
-+#if OS_VXWORKS
-+  if( rc==-1 && errno==ENOTSUP ){
-+    rc = fsync(fd);
-   }
-+#endif /* OS_VXWORKS */
-+#endif /* ifdef SQLITE_NO_SYNC elif HAVE_FULLFSYNC */
- 
--  do{
--    sqlite3_snprintf(nBuf-18, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir);
--    j = (int)strlen(zBuf);
--    sqlite3_randomness(15, &zBuf[j]);
--    for(i=0; i<15; i++, j++){
--      zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
--    }
--    zBuf[j] = 0;
--    zBuf[j+1] = 0;
--  }while( osAccess(zBuf,0)==0 );
--  return SQLITE_OK;
-+  if( OS_VXWORKS && rc!= -1 ){
-+    rc = 0;
-+  }
-+  return rc;
- }
- 
--#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
- /*
--** Routine to transform a unixFile into a proxy-locking unixFile.
--** Implementation in the proxy-lock division, but used by unixOpen()
--** if SQLITE_PREFER_PROXY_LOCKING is defined.
-+** Open a file descriptor to the directory containing file zFilename.
-+** If successful, *pFd is set to the opened file descriptor and
-+** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM
-+** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined
-+** value.
-+**
-+** The directory file descriptor is used for only one thing - to
-+** fsync() a directory to make sure file creation and deletion events
-+** are flushed to disk.  Such fsyncs are not needed on newer
-+** journaling filesystems, but are required on older filesystems.
-+**
-+** This routine can be overridden using the xSetSysCall interface.
-+** The ability to override this routine was added in support of the
-+** chromium sandbox.  Opening a directory is a security risk (we are
-+** told) so making it overrideable allows the chromium sandbox to
-+** replace this routine with a harmless no-op.  To make this routine
-+** a no-op, replace it with a stub that returns SQLITE_OK but leaves
-+** *pFd set to a negative number.
-+**
-+** If SQLITE_OK is returned, the caller is responsible for closing
-+** the file descriptor *pFd using close().
- */
--static int proxyTransformUnixFile(unixFile*, const char*);
--#endif
-+static int openDirectory(const char *zFilename, int *pFd){
-+  int ii;
-+  int fd = -1;
-+  char zDirname[MAX_PATHNAME+1];
-+
-+  sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename);
-+  for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--);
-+  if( ii>0 ){
-+    zDirname[ii] = '\0';
-+    fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
-+    if( fd>=0 ){
-+      OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
-+    }
-+  }
-+  *pFd = fd;
-+  return (fd>=0?SQLITE_OK:unixLogError(SQLITE_CANTOPEN_BKPT, "open", zDirname));
-+}
- 
- /*
--** Search for an unused file descriptor that was opened on the database 
--** file (not a journal or master-journal file) identified by pathname
--** zPath with SQLITE_OPEN_XXX flags matching those passed as the second
--** argument to this function.
-+** Make sure all writes to a particular file are committed to disk.
- **
--** Such a file descriptor may exist if a database connection was closed
--** but the associated file descriptor could not be closed because some
--** other file descriptor open on the same file is holding a file-lock.
--** Refer to comments in the unixClose() function and the lengthy comment
--** describing "Posix Advisory Locking" at the start of this file for 
--** further details. Also, ticket #4018.
-+** If dataOnly==0 then both the file itself and its metadata (file
-+** size, access time, etc) are synced.  If dataOnly!=0 then only the
-+** file data is synced.
- **
--** If a suitable file descriptor is found, then it is returned. If no
--** such file descriptor is located, -1 is returned.
-+** Under Unix, also make sure that the directory entry for the file
-+** has been created by fsync-ing the directory that contains the file.
-+** If we do not do this and we encounter a power failure, the directory
-+** entry for the journal might not exist after we reboot.  The next
-+** SQLite to access the file will not know that the journal exists (because
-+** the directory entry for the journal was never created) and the transaction
-+** will not roll back - possibly leading to database corruption.
- */
--static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
--  UnixUnusedFd *pUnused = 0;
-+static int unixSync(sqlite3_file *id, int flags){
-+  int rc;
-+  unixFile *pFile = (unixFile*)id;
- 
--  /* Do not search for an unused file descriptor on vxworks. Not because
--  ** vxworks would not benefit from the change (it might, we're not sure),
--  ** but because no way to test it is currently available. It is better 
--  ** not to risk breaking vxworks support for the sake of such an obscure 
--  ** feature.  */
--#if !OS_VXWORKS
--  struct stat sStat;                   /* Results of stat() call */
-+  int isDataOnly = (flags&SQLITE_SYNC_DATAONLY);
-+  int isFullsync = (flags&0x0F)==SQLITE_SYNC_FULL;
- 
--  /* A stat() call may fail for various reasons. If this happens, it is
--  ** almost certain that an open() call on the same path will also fail.
--  ** For this reason, if an error occurs in the stat() call here, it is
--  ** ignored and -1 is returned. The caller will try to open a new file
--  ** 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.  */
--  if( 0==osStat(zPath, &sStat) ){
--    unixInodeInfo *pInode;
-+  /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */
-+  assert((flags&0x0F)==SQLITE_SYNC_NORMAL
-+      || (flags&0x0F)==SQLITE_SYNC_FULL
-+  );
- 
--    unixEnterMutex();
--    pInode = inodeList;
--    while( pInode && (pInode->fileId.dev!=sStat.st_dev
--                     || pInode->fileId.ino!=sStat.st_ino) ){
--       pInode = pInode->pNext;
--    }
--    if( pInode ){
--      UnixUnusedFd **pp;
--      for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext));
--      pUnused = *pp;
--      if( pUnused ){
--        *pp = pUnused->pNext;
--      }
-+  /* 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 );
-+
-+  assert( pFile );
-+  OSTRACE(("SYNC    %-3d\n", pFile->h));
-+  rc = full_fsync(pFile->h, isFullsync, isDataOnly);
-+  SimulateIOError( rc=1 );
-+  if( rc ){
-+    pFile->lastErrno = errno;
-+    return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath);
-+  }
-+
-+  /* Also fsync the directory containing the file if the DIRSYNC flag
-+  ** is set.  This is a one-time occurrence.  Many systems (examples: AIX)
-+  ** are unable to fsync a directory, so ignore errors on the fsync.
-+  */
-+  if( pFile->ctrlFlags & UNIXFILE_DIRSYNC ){
-+    int dirfd;
-+    OSTRACE(("DIRSYNC %s (have_fullfsync=%d fullsync=%d)\n", pFile->zPath,
-+            HAVE_FULLFSYNC, isFullsync));
-+    rc = osOpenDirectory(pFile->zPath, &dirfd);
-+    if( rc==SQLITE_OK && dirfd>=0 ){
-+      full_fsync(dirfd, 0, 0);
-+      robust_close(pFile, dirfd, __LINE__);
-+    }else if( rc==SQLITE_CANTOPEN ){
-+      rc = SQLITE_OK;
-     }
--    unixLeaveMutex();
-+    pFile->ctrlFlags &= ~UNIXFILE_DIRSYNC;
-   }
--#endif    /* if !OS_VXWORKS */
--  return pUnused;
-+  return rc;
- }
- 
- /*
--** This function is called by unixOpen() to determine the unix permissions
--** to create new files with. If no error occurs, then SQLITE_OK is returned
--** and a value suitable for passing as the third argument to open(2) is
--** 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
--** 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 
--** this function queries the file-system for the permissions on the 
--** corresponding database file and sets *pMode to this value. Whenever 
--** possible, WAL and journal files are created using the same permissions 
--** as the associated database file.
--**
--** If the SQLITE_ENABLE_8_3_NAMES option is enabled, then the
--** original filename is unavailable.  But 8_3_NAMES is only used for
--** FAT filesystems and permissions do not matter there, so just use
--** the default permissions.
-+** Truncate an open file to a specified size
- */
--static int findCreateFileMode(
--  const char *zPath,              /* Path of file (possibly) being created */
--  int flags,                      /* Flags passed as 4th argument to xOpen() */
--  mode_t *pMode,                  /* OUT: Permissions to open file with */
--  uid_t *pUid,                    /* OUT: uid to set on the file */
--  gid_t *pGid                     /* OUT: gid to set on the file */
--){
--  int rc = SQLITE_OK;             /* Return Code */
--  *pMode = 0;
--  *pUid = 0;
--  *pGid = 0;
--  if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
--    char zDb[MAX_PATHNAME+1];     /* Database file path */
--    int nDb;                      /* Number of valid bytes in zDb */
--    struct stat sStat;            /* Output of stat() on database file */
-+static int unixTruncate(sqlite3_file *id, i64 nByte){
-+  unixFile *pFile = (unixFile *)id;
-+  int rc;
-+  assert( pFile );
-+  SimulateIOError( return SQLITE_IOERR_TRUNCATE );
- 
--    /* zPath is a path to a WAL or journal file. The following block derives
--    ** the path to the associated database file from zPath. This block handles
--    ** the following naming conventions:
--    **
--    **   "<path to db>-journal"
--    **   "<path to db>-wal"
--    **   "<path to db>-journalNN"
--    **   "<path to db>-walNN"
--    **
--    ** where NN is a decimal number. The NN naming schemes are 
--    ** used by the test_multiplex.c module.
--    */
--    nDb = sqlite3Strlen30(zPath) - 1; 
--#ifdef SQLITE_ENABLE_8_3_NAMES
--    while( nDb>0 && sqlite3Isalnum(zPath[nDb]) ) nDb--;
--    if( nDb==0 || zPath[nDb]!='-' ) return SQLITE_OK;
--#else
--    while( zPath[nDb]!='-' ){
--      assert( nDb>0 );
--      assert( zPath[nDb]!='\n' );
--      nDb--;
-+  /* 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;
-+  }
-+
-+  rc = robust_ftruncate(pFile->h, (off_t)nByte);
-+  if( rc ){
-+    pFile->lastErrno = errno;
-+    return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
-+  }else{
-+#ifdef SQLITE_DEBUG
-+    /* If we are doing a normal write to a database file (as opposed to
-+    ** doing a hot-journal rollback or a write to some file other than a
-+    ** normal database file) and we truncate the file to zero length,
-+    ** that effectively updates the change counter.  This might happen
-+    ** when restoring a database using the backup API from a zero-length
-+    ** source.
-+    */
-+    if( pFile->inNormalWrite && nByte==0 ){
-+      pFile->transCntrChng = 1;
-     }
- #endif
--    memcpy(zDb, zPath, nDb);
--    zDb[nDb] = '\0';
- 
--    if( 0==osStat(zDb, &sStat) ){
--      *pMode = sStat.st_mode & 0777;
--      *pUid = sStat.st_uid;
--      *pGid = sStat.st_gid;
--    }else{
--      rc = SQLITE_IOERR_FSTAT;
-+    /* If the file was just 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( nByte<pFile->mmapSize ){
-+      pFile->mmapSize = nByte;
-     }
--  }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){
--    *pMode = 0600;
-+
-+    return SQLITE_OK;
-   }
--  return rc;
- }
- 
- /*
--** Open the file zPath.
--** 
--** Previously, the SQLite OS layer used three functions in place of this
--** one:
--**
--**     sqlite3OsOpenReadWrite();
--**     sqlite3OsOpenReadOnly();
--**     sqlite3OsOpenExclusive();
--**
--** These calls correspond to the following combinations of flags:
--**
--**     ReadWrite() ->     (READWRITE | CREATE)
--**     ReadOnly()  ->     (READONLY) 
--**     OpenExclusive() -> (READWRITE | CREATE | EXCLUSIVE)
--**
--** The old OpenExclusive() accepted a boolean argument - "delFlag". If
--** true, the file was configured to be automatically deleted when the
--** file handle closed. To achieve the same effect using this new 
--** interface, add the DELETEONCLOSE flag to those specified above for 
--** OpenExclusive().
-+** Determine the current size of a file in bytes
- */
--static int unixOpen(
--  sqlite3_vfs *pVfs,           /* The VFS for which this is the xOpen method */
--  const char *zPath,           /* Pathname of file to be opened */
--  sqlite3_file *pFile,         /* The file descriptor to be filled in */
--  int flags,                   /* Input flags to control the opening */
--  int *pOutFlags               /* Output flags returned to SQLite core */
--){
--  unixFile *p = (unixFile *)pFile;
--  int fd = -1;                   /* File descriptor returned by open() */
--  int openFlags = 0;             /* Flags to pass to open() */
--  int eType = flags&0xFFFFFF00;  /* Type of file to open */
--  int noLock;                    /* True to omit locking primitives */
--  int rc = SQLITE_OK;            /* Function Return Code */
--  int ctrlFlags = 0;             /* UNIXFILE_* flags */
--
--  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 SQLITE_ENABLE_LOCKING_STYLE
--  int isAutoProxy  = (flags & SQLITE_OPEN_AUTOPROXY);
--#endif
--#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
--  struct statfs fsInfo;
--#endif
-+static int unixFileSize(sqlite3_file *id, i64 *pSize){
-+  int rc;
-+  struct stat buf;
-+  assert( id );
-+  rc = osFstat(((unixFile*)id)->h, &buf);
-+  SimulateIOError( rc=1 );
-+  if( rc!=0 ){
-+    ((unixFile*)id)->lastErrno = errno;
-+    return SQLITE_IOERR_FSTAT;
-+  }
-+  *pSize = buf.st_size;
- 
--  /* If creating a master or main-file journal, this function will open
--  ** a file-descriptor on the directory too. The first time unixSync()
--  ** is called the directory file descriptor will be fsync()ed and close()d.
-+  /* When opening a zero-size database, the findInodeInfo() procedure
-+  ** writes a single byte into that file in order to work around a bug
-+  ** in the OS-X msdos filesystem.  In order to avoid problems with upper
-+  ** layers, we need to report this file size as zero even though it is
-+  ** really 1.   Ticket #3260.
-   */
--  int syncDir = (isCreate && (
--        eType==SQLITE_OPEN_MASTER_JOURNAL 
--     || eType==SQLITE_OPEN_MAIN_JOURNAL 
--     || eType==SQLITE_OPEN_WAL
--  ));
-+  if( *pSize==1 ) *pSize = 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[MAX_PATHNAME+2];
--  const char *zName = zPath;
- 
--  /* 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);
-+  return SQLITE_OK;
-+}
- 
--  /* 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 );
-+#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
-+/*
-+** Handler for proxy-locking file-control verbs.  Defined below in the
-+** proxying locking division.
-+*/
-+static int proxyFileControl(sqlite3_file*,int,void*);
-+#endif
- 
--  /* 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
--  );
-+/* 
-+** This function is called to handle the SQLITE_FCNTL_SIZE_HINT 
-+** file-control operation.  Enlarge the database to nBytes in size
-+** (rounded up to the next chunk-size).  If the database is already
-+** nBytes or larger, this routine is a no-op.
-+*/
-+static int fcntlSizeHint(unixFile *pFile, i64 nByte){
-+  if( pFile->szChunk>0 ){
-+    i64 nSize;                    /* Required file size */
-+    struct stat buf;              /* Used to hold return values of fstat() */
-+   
-+    if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT;
- 
--  memset(p, 0, sizeof(unixFile));
-+    nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk;
-+    if( nSize>(i64)buf.st_size ){
- 
--  if( eType==SQLITE_OPEN_MAIN_DB ){
--    UnixUnusedFd *pUnused;
--    pUnused = findReusableFd(zName, flags);
--    if( pUnused ){
--      fd = pUnused->fd;
--    }else{
--      pUnused = sqlite3_malloc(sizeof(*pUnused));
--      if( !pUnused ){
--        return SQLITE_NOMEM;
-+#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
-+      /* The code below is handling the return value of osFallocate() 
-+      ** correctly. posix_fallocate() is defined to "returns zero on success, 
-+      ** or an error number on  failure". See the manpage for details. */
-+      int err;
-+      do{
-+        err = osFallocate(pFile->h, buf.st_size, nSize-buf.st_size);
-+      }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.
-+      */
-+      int nBlk = buf.st_blksize;  /* File-system block size */
-+      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);
-+        if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
-+        iWrite += nBlk;
-       }
-+#endif
-     }
--    p->pUnused = pUnused;
--
--    /* Database filenames are double-zero terminated if they are not
--    ** URIs with parameters.  Hence, they can always be passed into
--    ** sqlite3_uri_parameter(). */
--    assert( (flags & SQLITE_OPEN_URI) || zName[strlen(zName)+1]==0 );
-+  }
- 
--  }else if( !zName ){
--    /* If zName is NULL, the upper layer is requesting a temp file. */
--    assert(isDelete && !syncDir);
--    rc = unixGetTempname(MAX_PATHNAME+2, zTmpname);
--    if( rc!=SQLITE_OK ){
--      return rc;
-+  if( pFile->mmapSizeMax>0 && nByte>pFile->mmapSize ){
-+    int rc;
-+    if( pFile->szChunk<=0 ){
-+      if( robust_ftruncate(pFile->h, nByte) ){
-+        pFile->lastErrno = errno;
-+        return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
-+      }
-     }
--    zName = zTmpname;
- 
--    /* Generated temporary filenames are always double-zero terminated
--    ** for use by sqlite3_uri_parameter(). */
--    assert( zName[strlen(zName)+1]==0 );
-+    rc = unixMapfile(pFile, nByte);
-+    return rc;
-   }
- 
--  /* Determine the value of the flags parameter passed to POSIX function
--  ** open(). These must be calculated even if open() is not called, as
--  ** they may be stored as part of the file handle and used by the 
--  ** 'conch file' locking functions later on.  */
--  if( isReadonly )  openFlags |= O_RDONLY;
--  if( isReadWrite ) openFlags |= O_RDWR;
--  if( isCreate )    openFlags |= O_CREAT;
--  if( isExclusive ) openFlags |= (O_EXCL|O_NOFOLLOW);
--  openFlags |= (O_LARGEFILE|O_BINARY);
-+  return SQLITE_OK;
-+}
- 
--  if( fd<0 ){
--    mode_t openMode;              /* Permissions to create file with */
--    uid_t uid;                    /* Userid for the file */
--    gid_t gid;                    /* Groupid for the file */
--    rc = findCreateFileMode(zName, flags, &openMode, &uid, &gid);
--    if( rc!=SQLITE_OK ){
--      assert( !p->pUnused );
--      assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL );
-+/*
-+** If *pArg is inititially 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.
-+*/
-+static void unixModeBit(unixFile *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;
-+  }
-+}
-+
-+/* Forward declaration */
-+static int unixGetTempname(int nBuf, char *zBuf);
-+
-+/*
-+** Information and control of an open file handle.
-+*/
-+static int unixFileControl(sqlite3_file *id, int op, void *pArg){
-+  unixFile *pFile = (unixFile*)id;
-+  switch( op ){
-+    case SQLITE_FCNTL_LOCKSTATE: {
-+      *(int*)pArg = pFile->eFileLock;
-+      return SQLITE_OK;
-+    }
-+    case SQLITE_LAST_ERRNO: {
-+      *(int*)pArg = pFile->lastErrno;
-+      return SQLITE_OK;
-+    }
-+    case SQLITE_FCNTL_CHUNK_SIZE: {
-+      pFile->szChunk = *(int *)pArg;
-+      return SQLITE_OK;
-+    }
-+    case SQLITE_FCNTL_SIZE_HINT: {
-+      int rc;
-+      SimulateIOErrorBenign(1);
-+      rc = fcntlSizeHint(pFile, *(i64 *)pArg);
-+      SimulateIOErrorBenign(0);
-       return rc;
-     }
--    fd = robust_open(zName, openFlags, openMode);
--    OSTRACE(("OPENX   %-3d %s 0%o\n", fd, zName, openFlags));
--    if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){
--      /* Failed to open the file for read/write access. Try read-only. */
--      flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
--      openFlags &= ~(O_RDWR|O_CREAT);
--      flags |= SQLITE_OPEN_READONLY;
--      openFlags |= O_RDONLY;
--      isReadonly = 1;
--      fd = robust_open(zName, openFlags, openMode);
-+    case SQLITE_FCNTL_PERSIST_WAL: {
-+      unixModeBit(pFile, UNIXFILE_PERSIST_WAL, (int*)pArg);
-+      return SQLITE_OK;
-     }
--    if( fd<0 ){
--      rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
--      goto open_finished;
-+    case SQLITE_FCNTL_POWERSAFE_OVERWRITE: {
-+      unixModeBit(pFile, UNIXFILE_PSOW, (int*)pArg);
-+      return SQLITE_OK;
-     }
--
--    /* If this process is running as root and if creating a new rollback
--    ** journal or WAL file, set the ownership of the journal or WAL to be
--    ** the same as the original database.
-+    case SQLITE_FCNTL_VFSNAME: {
-+      *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
-+      return SQLITE_OK;
-+    }
-+    case SQLITE_FCNTL_TEMPFILENAME: {
-+      char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
-+      if( zTFile ){
-+        unixGetTempname(pFile->pVfs->mxPathname, zTFile);
-+        *(char**)pArg = zTFile;
-+      }
-+      return SQLITE_OK;
-+    }
-+    case SQLITE_FCNTL_MMAP_SIZE: {
-+      i64 newLimit = *(i64*)pArg;
-+      if( newLimit>sqlite3GlobalConfig.mxMmap ){
-+        newLimit = sqlite3GlobalConfig.mxMmap;
-+      }
-+      *(i64*)pArg = pFile->mmapSizeMax;
-+      if( newLimit>=0 ){
-+        pFile->mmapSizeMax = newLimit;
-+        if( newLimit<pFile->mmapSize ) pFile->mmapSize = newLimit;
-+      }
-+      return SQLITE_OK;
-+    }
-+#ifdef SQLITE_DEBUG
-+    /* The pager calls this method to signal that it has done
-+    ** a rollback and that the database is therefore unchanged and
-+    ** it hence it is OK for the transaction change counter to be
-+    ** unchanged.
-     */
--    if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
--      osFchown(fd, uid, gid);
-+    case SQLITE_FCNTL_DB_UNCHANGED: {
-+      ((unixFile*)id)->dbUpdate = 0;
-+      return SQLITE_OK;
-     }
--  }
--  assert( fd>=0 );
--  if( pOutFlags ){
--    *pOutFlags = flags;
--  }
--
--  if( p->pUnused ){
--    p->pUnused->fd = fd;
--    p->pUnused->flags = flags;
--  }
--
--  if( isDelete ){
--#if OS_VXWORKS
--    zPath = zName;
--#else
--    osUnlink(zName);
- #endif
-+#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
-+    case SQLITE_SET_LOCKPROXYFILE:
-+    case SQLITE_GET_LOCKPROXYFILE: {
-+      return proxyFileControl(id,op,pArg);
-+    }
-+#endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */
-   }
--#if SQLITE_ENABLE_LOCKING_STYLE
--  else{
--    p->openFlags = openFlags;
--  }
--#endif
--
--  noLock = eType!=SQLITE_OPEN_MAIN_DB;
-+  return SQLITE_NOTFOUND;
-+}
- 
--  
--#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
--  if( fstatfs(fd, &fsInfo) == -1 ){
--    ((unixFile*)pFile)->lastErrno = 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;
--  }
-+/*
-+** 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.
-+*/
-+#ifndef __QNXNTO__ 
-+static int unixSectorSize(sqlite3_file *NotUsed){
-+  UNUSED_PARAMETER(NotUsed);
-+  return SQLITE_DEFAULT_SECTOR_SIZE;
-+}
- #endif
- 
--  /* Set up appropriate ctrlFlags */
--  if( isDelete )                ctrlFlags |= UNIXFILE_DELETE;
--  if( isReadonly )              ctrlFlags |= UNIXFILE_RDONLY;
--  if( noLock )                  ctrlFlags |= UNIXFILE_NOLOCK;
--  if( syncDir )                 ctrlFlags |= UNIXFILE_DIRSYNC;
--  if( flags & SQLITE_OPEN_URI ) ctrlFlags |= UNIXFILE_URI;
--
--#if SQLITE_ENABLE_LOCKING_STYLE
--#if SQLITE_PREFER_PROXY_LOCKING
--  isAutoProxy = 1;
--#endif
--  if( isAutoProxy && (zPath!=NULL) && (!noLock) && pVfs->xOpen ){
--    char *envforce = getenv("SQLITE_FORCE_PROXY_LOCKING");
--    int useProxy = 0;
-+/*
-+** The following version of unixSectorSize() is optimized for QNX.
-+*/
-+#ifdef __QNXNTO__
-+#include <sys/dcmd_blk.h>
-+#include <sys/statvfs.h>
-+static int unixSectorSize(sqlite3_file *id){
-+  unixFile *pFile = (unixFile*)id;
-+  if( pFile->sectorSize == 0 ){
-+    struct statvfs fsInfo;
-+       
-+    /* Set defaults for non-supported filesystems */
-+    pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
-+    pFile->deviceCharacteristics = 0;
-+    if( fstatvfs(pFile->h, &fsInfo) == -1 ) {
-+      return pFile->sectorSize;
-+    }
- 
--    /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, 0 means 
--    ** never use proxy, NULL means use proxy for non-local files only.  */
--    if( envforce!=NULL ){
--      useProxy = atoi(envforce)>0;
-+    if( !strcmp(fsInfo.f_basetype, "tmp") ) {
-+      pFile->sectorSize = fsInfo.f_bsize;
-+      pFile->deviceCharacteristics =
-+        SQLITE_IOCAP_ATOMIC4K |       /* All ram filesystem writes are atomic */
-+        SQLITE_IOCAP_SAFE_APPEND |    /* growing the file does not occur until
-+                                      ** the write succeeds */
-+        SQLITE_IOCAP_SEQUENTIAL |     /* The ram filesystem has no write behind
-+                                      ** so it is ordered */
-+        0;
-+    }else if( strstr(fsInfo.f_basetype, "etfs") ){
-+      pFile->sectorSize = fsInfo.f_bsize;
-+      pFile->deviceCharacteristics =
-+        /* etfs cluster size writes are atomic */
-+        (pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) |
-+        SQLITE_IOCAP_SAFE_APPEND |    /* growing the file does not occur until
-+                                      ** the write succeeds */
-+        SQLITE_IOCAP_SEQUENTIAL |     /* The ram filesystem has no write behind
-+                                      ** so it is ordered */
-+        0;
-+    }else if( !strcmp(fsInfo.f_basetype, "qnx6") ){
-+      pFile->sectorSize = fsInfo.f_bsize;
-+      pFile->deviceCharacteristics =
-+        SQLITE_IOCAP_ATOMIC |         /* All filesystem writes are atomic */
-+        SQLITE_IOCAP_SAFE_APPEND |    /* growing the file does not occur until
-+                                      ** the write succeeds */
-+        SQLITE_IOCAP_SEQUENTIAL |     /* The ram filesystem has no write behind
-+                                      ** so it is ordered */
-+        0;
-+    }else if( !strcmp(fsInfo.f_basetype, "qnx4") ){
-+      pFile->sectorSize = fsInfo.f_bsize;
-+      pFile->deviceCharacteristics =
-+        /* full bitset of atomics from max sector size and smaller */
-+        ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 |
-+        SQLITE_IOCAP_SEQUENTIAL |     /* The ram filesystem has no write behind
-+                                      ** so it is ordered */
-+        0;
-+    }else if( strstr(fsInfo.f_basetype, "dos") ){
-+      pFile->sectorSize = fsInfo.f_bsize;
-+      pFile->deviceCharacteristics =
-+        /* full bitset of atomics from max sector size and smaller */
-+        ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 |
-+        SQLITE_IOCAP_SEQUENTIAL |     /* The ram filesystem has no write behind
-+                                      ** so it is ordered */
-+        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 ){
--      rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags);
--      if( rc==SQLITE_OK ){
--        rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:");
--        if( rc!=SQLITE_OK ){
--          /* Use unixClose to clean up the resources added in fillInUnixFile 
--          ** and clear all the structure's references.  Specifically, 
--          ** pFile->pMethods will be NULL so sqlite3OsClose will be a no-op 
--          */
--          unixClose(pFile);
--          return rc;
--        }
--      }
--      goto open_finished;
-+      pFile->deviceCharacteristics =
-+        SQLITE_IOCAP_ATOMIC512 |      /* blocks are atomic */
-+        SQLITE_IOCAP_SAFE_APPEND |    /* growing the file does not occur until
-+                                      ** the write succeeds */
-+        0;
-     }
-   }
--#endif
--  
--  rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags);
--
--open_finished:
--  if( rc!=SQLITE_OK ){
--    sqlite3_free(p->pUnused);
-+  /* Last chance verification.  If the sector size isn't a multiple of 512
-+  ** then it isn't valid.*/
-+  if( pFile->sectorSize % 512 != 0 ){
-+    pFile->deviceCharacteristics = 0;
-+    pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
-   }
--  return rc;
-+  return pFile->sectorSize;
- }
--
-+#endif /* __QNXNTO__ */
- 
- /*
--** Delete the file at zPath. If the dirSync argument is true, fsync()
--** the directory after deleting the file.
-+** 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
-+** 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,
-+** very rare.  And asserting PSOW makes a large reduction in the amount
-+** of required I/O for journaling, since a lot of padding is eliminated.
-+**  Hence, while POWERSAFE_OVERWRITE is on by default, there is a file-control
-+** available to turn it off and URI query parameter available to turn it off.
- */
--static int unixDelete(
--  sqlite3_vfs *NotUsed,     /* VFS containing this as the xDelete method */
--  const char *zPath,        /* Name of file to be deleted */
--  int dirSync               /* If true, fsync() directory after deleting file */
--){
--  int rc = SQLITE_OK;
--  UNUSED_PARAMETER(NotUsed);
--  SimulateIOError(return SQLITE_IOERR_DELETE);
--  if( osUnlink(zPath)==(-1) ){
--    if( errno==ENOENT ){
--      rc = SQLITE_IOERR_DELETE_NOENT;
--    }else{
--      rc = unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath);
--    }
--    return rc;
--  }
--#ifndef SQLITE_DISABLE_DIRSYNC
--  if( (dirSync & 1)!=0 ){
--    int fd;
--    rc = osOpenDirectory(zPath, &fd);
--    if( rc==SQLITE_OK ){
--#if OS_VXWORKS
--      if( fsync(fd)==-1 )
--#else
--      if( fsync(fd) )
-+static int unixDeviceCharacteristics(sqlite3_file *id){
-+  unixFile *p = (unixFile*)id;
-+  int rc = 0;
-+#ifdef __QNXNTO__
-+  if( p->sectorSize==0 ) unixSectorSize(id);
-+  rc = p->deviceCharacteristics;
- #endif
--      {
--        rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath);
--      }
--      robust_close(0, fd, __LINE__);
--    }else if( rc==SQLITE_CANTOPEN ){
--      rc = SQLITE_OK;
--    }
-+  if( p->ctrlFlags & UNIXFILE_PSOW ){
-+    rc |= SQLITE_IOCAP_POWERSAFE_OVERWRITE;
-   }
--#endif
-   return rc;
- }
- 
-+#ifndef SQLITE_OMIT_WAL
-+
-+
- /*
--** Test the existence of or access permissions of file zPath. The
--** test performed depends on the value of flags:
-+** Object used to represent an shared memory buffer.  
- **
--**     SQLITE_ACCESS_EXISTS: Return 1 if the file exists
--**     SQLITE_ACCESS_READWRITE: Return 1 if the file is read and writable.
--**     SQLITE_ACCESS_READONLY: Return 1 if the file is readable.
-+** When multiple threads all reference the same wal-index, each thread
-+** has its own unixShm object, but they all point to a single instance
-+** of this unixShmNode object.  In other words, each wal-index is opened
-+** only once per process.
- **
--** Otherwise return 0.
-+** Each unixShmNode object is connected to a single unixInodeInfo object.
-+** We could coalesce this object into unixInodeInfo, but that would mean
-+** every open file that does not use shared memory (in other words, most
-+** open files) would have to carry around this extra information.  So
-+** the unixInodeInfo object contains a pointer to this unixShmNode object
-+** and the unixShmNode object is created only when needed.
-+**
-+** unixMutexHeld() must be true when creating or destroying
-+** this object or while reading or writing the following fields:
-+**
-+**      nRef
-+**
-+** The following fields are read-only after the object is created:
-+** 
-+**      fid
-+**      zFilename
-+**
-+** Either unixShmNode.mutex must be held or unixShmNode.nRef==0 and
-+** unixMutexHeld() is true when reading or writing any other field
-+** in this structure.
- */
--static int unixAccess(
--  sqlite3_vfs *NotUsed,   /* The VFS containing this xAccess method */
--  const char *zPath,      /* Path of the file to examine */
--  int flags,              /* What do we want to learn about the zPath file? */
--  int *pResOut            /* Write result boolean here */
--){
--  int amode = 0;
--  UNUSED_PARAMETER(NotUsed);
--  SimulateIOError( return SQLITE_IOERR_ACCESS; );
--  switch( flags ){
--    case SQLITE_ACCESS_EXISTS:
--      amode = F_OK;
--      break;
--    case SQLITE_ACCESS_READWRITE:
--      amode = W_OK|R_OK;
--      break;
--    case SQLITE_ACCESS_READ:
--      amode = R_OK;
--      break;
-+struct unixShmNode {
-+  unixInodeInfo *pInode;     /* unixInodeInfo that owns this SHM node */
-+  sqlite3_mutex *mutex;      /* Mutex to access this object */
-+  char *zFilename;           /* Name of the mmapped file */
-+  int h;                     /* Open file descriptor */
-+  int szRegion;              /* Size of shared-memory regions */
-+  u16 nRegion;               /* Size of array apRegion */
-+  u8 isReadonly;             /* True if read-only */
-+  char **apRegion;           /* Array of mapped shared-memory regions */
-+  int nRef;                  /* Number of unixShm objects pointing to this */
-+  unixShm *pFirst;           /* All unixShm objects pointing to this */
-+#ifdef SQLITE_DEBUG
-+  u8 exclMask;               /* Mask of exclusive locks held */
-+  u8 sharedMask;             /* Mask of shared locks held */
-+  u8 nextShmId;              /* Next available unixShm.id value */
-+#endif
-+};
- 
--    default:
--      assert(!"Invalid flags argument");
--  }
--  *pResOut = (osAccess(zPath, amode)==0);
--  if( flags==SQLITE_ACCESS_EXISTS && *pResOut ){
--    struct stat buf;
--    if( 0==osStat(zPath, &buf) && buf.st_size==0 ){
--      *pResOut = 0;
--    }
--  }
--  return SQLITE_OK;
--}
-+/*
-+** 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:
-+**
-+**    unixShm.pFile
-+**    unixShm.id
-+**
-+** All other fields are read/write.  The unixShm.pFile->mutex must be held
-+** while accessing any read/write fields.
-+*/
-+struct unixShm {
-+  unixShmNode *pShmNode;     /* The underlying unixShmNode object */
-+  unixShm *pNext;            /* Next unixShm with the same unixShmNode */
-+  u8 hasMutex;               /* True if holding the unixShmNode mutex */
-+  u8 id;                     /* Id of this connection within its unixShmNode */
-+  u16 sharedMask;            /* Mask of shared locks held */
-+  u16 exclMask;              /* Mask of exclusive locks held */
-+};
- 
-+/*
-+** Constants used for locking
-+*/
-+#define UNIX_SHM_BASE   ((22+SQLITE_SHM_NLOCK)*4)         /* first lock byte */
-+#define UNIX_SHM_DMS    (UNIX_SHM_BASE+SQLITE_SHM_NLOCK)  /* deadman switch */
- 
- /*
--** Turn a relative pathname into a full pathname. The relative path
--** is stored as a nul-terminated string in the buffer pointed to by
--** zPath. 
-+** Apply posix advisory locks for all bytes from ofst through ofst+n-1.
- **
--** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes 
--** (in this case, MAX_PATHNAME bytes). The full-path is written to
--** this buffer before returning.
-+** Locks block if the mask is exactly UNIX_SHM_C and are non-blocking
-+** otherwise.
- */
--static int unixFullPathname(
--  sqlite3_vfs *pVfs,            /* Pointer to vfs object */
--  const char *zPath,            /* Possibly relative input path */
--  int nOut,                     /* Size of output buffer in bytes */
--  char *zOut                    /* Output buffer */
-+static int unixShmSystemLock(
-+  unixShmNode *pShmNode, /* Apply locks to this open shared-memory segment */
-+  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() */
- 
--  /* 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 );
-+  /* Access to the unixShmNode object is serialized by the caller */
-+  assert( sqlite3_mutex_held(pShmNode->mutex) || pShmNode->nRef==0 );
- 
--  assert( pVfs->mxPathname==MAX_PATHNAME );
--  UNUSED_PARAMETER(pVfs);
-+  /* Shared locks never span more than one byte */
-+  assert( n==1 || lockType!=F_RDLCK );
- 
--  zOut[nOut-1] = '\0';
--  if( zPath[0]=='/' ){
--    sqlite3_snprintf(nOut, zOut, "%s", zPath);
-+  /* Locks are within range */
-+  assert( n>=1 && n<SQLITE_SHM_NLOCK );
-+
-+  if( pShmNode->h>=0 ){
-+    /* Initialize the locking parameters */
-+    memset(&f, 0, sizeof(f));
-+    f.l_type = lockType;
-+    f.l_whence = SEEK_SET;
-+    f.l_start = ofst;
-+    f.l_len = n;
-+
-+    rc = osFcntl(pShmNode->h, F_SETLK, &f);
-+    rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
-+  }
-+
-+  /* Update the global lock state and do debug tracing */
-+#ifdef SQLITE_DEBUG
-+  { u16 mask;
-+  OSTRACE(("SHM-LOCK "));
-+  mask = (1<<(ofst+n)) - (1<<ofst);
-+  if( rc==SQLITE_OK ){
-+    if( lockType==F_UNLCK ){
-+      OSTRACE(("unlock %d ok", ofst));
-+      pShmNode->exclMask &= ~mask;
-+      pShmNode->sharedMask &= ~mask;
-+    }else if( lockType==F_RDLCK ){
-+      OSTRACE(("read-lock %d ok", ofst));
-+      pShmNode->exclMask &= ~mask;
-+      pShmNode->sharedMask |= mask;
-+    }else{
-+      assert( lockType==F_WRLCK );
-+      OSTRACE(("write-lock %d ok", ofst));
-+      pShmNode->exclMask |= mask;
-+      pShmNode->sharedMask &= ~mask;
-+    }
-   }else{
--    int nCwd;
--    if( osGetcwd(zOut, nOut-1)==0 ){
--      return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
-+    if( lockType==F_UNLCK ){
-+      OSTRACE(("unlock %d failed", ofst));
-+    }else if( lockType==F_RDLCK ){
-+      OSTRACE(("read-lock failed"));
-+    }else{
-+      assert( lockType==F_WRLCK );
-+      OSTRACE(("write-lock %d failed", ofst));
-     }
--    nCwd = (int)strlen(zOut);
--    sqlite3_snprintf(nOut-nCwd, &zOut[nCwd], "/%s", zPath);
-   }
--  return SQLITE_OK;
--}
--
-+  OSTRACE((" - afterwards %03x,%03x\n",
-+           pShmNode->sharedMask, pShmNode->exclMask));
-+  }
-+#endif
- 
--#ifndef SQLITE_OMIT_LOAD_EXTENSION
--/*
--** Interfaces for opening a shared library, finding entry points
--** within the shared library, and closing the shared library.
--*/
--#include <dlfcn.h>
--static void *unixDlOpen(sqlite3_vfs *NotUsed, const char *zFilename){
--  UNUSED_PARAMETER(NotUsed);
--  return dlopen(zFilename, RTLD_NOW | RTLD_GLOBAL);
-+  return rc;        
- }
- 
-+
- /*
--** SQLite calls this function immediately after a call to unixDlSym() or
--** unixDlOpen() fails (returns a null pointer). If a more detailed error
--** message is available, it is written to zBufOut. If no error message
--** is available, zBufOut is left unmodified and SQLite uses a default
--** error message.
-+** Purge the unixShmNodeList list of all entries with unixShmNode.nRef==0.
-+**
-+** This is not a VFS shared-memory method; it is a utility function called
-+** by VFS shared-memory methods.
- */
--static void unixDlError(sqlite3_vfs *NotUsed, int nBuf, char *zBufOut){
--  const char *zErr;
--  UNUSED_PARAMETER(NotUsed);
--  unixEnterMutex();
--  zErr = dlerror();
--  if( zErr ){
--    sqlite3_snprintf(nBuf, zBufOut, "%s", zErr);
-+static void unixShmPurge(unixFile *pFd){
-+  unixShmNode *p = pFd->pInode->pShmNode;
-+  assert( unixMutexHeld() );
-+  if( p && p->nRef==0 ){
-+    int i;
-+    assert( p->pInode==pFd->pInode );
-+    sqlite3_mutex_free(p->mutex);
-+    for(i=0; i<p->nRegion; i++){
-+      if( p->h>=0 ){
-+        osMunmap(p->apRegion[i], p->szRegion);
-+      }else{
-+        sqlite3_free(p->apRegion[i]);
-+      }
-+    }
-+    sqlite3_free(p->apRegion);
-+    if( p->h>=0 ){
-+      robust_close(pFd, p->h, __LINE__);
-+      p->h = -1;
-+    }
-+    p->pInode->pShmNode = 0;
-+    sqlite3_free(p);
-   }
--  unixLeaveMutex();
--}
--static void (*unixDlSym(sqlite3_vfs *NotUsed, void *p, const char*zSym))(void){
--  /* 
--  ** GCC with -pedantic-errors says that C90 does not allow a void* to be
--  ** cast into a pointer to a function.  And yet the library dlsym() routine
--  ** returns a void* which is really a pointer to a function.  So how do we
--  ** use dlsym() with -pedantic-errors?
--  **
--  ** Variable x below is defined to be a pointer to a function taking
--  ** parameters void* and const char* and returning a pointer to a function.
--  ** We initialize x by assigning it a pointer to the dlsym() function.
--  ** (That assignment requires a cast.)  Then we call the function that
--  ** x points to.  
--  **
--  ** This work-around is unlikely to work correctly on any system where
--  ** you really cannot cast a function pointer into void*.  But then, on the
--  ** other hand, dlsym() will not work on such a system either, so we have
--  ** not really lost anything.
--  */
--  void (*(*x)(void*,const char*))(void);
--  UNUSED_PARAMETER(NotUsed);
--  x = (void(*(*)(void*,const char*))(void))dlsym;
--  return (*x)(p, zSym);
--}
--static void unixDlClose(sqlite3_vfs *NotUsed, void *pHandle){
--  UNUSED_PARAMETER(NotUsed);
--  dlclose(pHandle);
- }
--#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
--  #define unixDlOpen  0
--  #define unixDlError 0
--  #define unixDlSym   0
--  #define unixDlClose 0
--#endif
- 
- /*
--** Write nBuf bytes of random data to the supplied buffer zBuf.
-+** Open a shared-memory area associated with open database file pDbFd.  
-+** This particular implementation uses mmapped files.
-+**
-+** The file used to implement shared-memory is in the same directory
-+** as the open database file and has the same name as the open database
-+** file with the "-shm" suffix added.  For example, if the database file
-+** is "/home/user1/config.db" then the file that is created and mmapped
-+** for shared memory will be called "/home/user1/config.db-shm".  
-+**
-+** Another approach to is to use files in /dev/shm or /dev/tmp or an
-+** some other tmpfs mount. But if a file in a different directory
-+** from the database file is used, then differing access permissions
-+** or a chroot() might cause two different processes on the same
-+** database to end up using different files for shared memory - 
-+** meaning that their memory would not really be shared - resulting
-+** in database corruption.  Nevertheless, this tmpfs file usage
-+** can be enabled at compile-time using -DSQLITE_SHM_DIRECTORY="/dev/shm"
-+** or the equivalent.  The use of the SQLITE_SHM_DIRECTORY compile-time
-+** option results in an incompatible build of SQLite;  builds of SQLite
-+** that with differing SQLITE_SHM_DIRECTORY settings attempt to use the
-+** same database file at the same time, database corruption will likely
-+** result. The SQLITE_SHM_DIRECTORY compile-time option is considered
-+** "unsupported" and may go away in a future SQLite release.
-+**
-+** 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.
-+**
-+** If the original database file (pDbFd) is using the "unix-excl" VFS
-+** that means that an exclusive lock is held on the database file and
-+** that no other processes are able to read or write the database.  In
-+** that case, we do not really need shared memory.  No shared memory
-+** file is created.  The shared memory will be simulated with heap memory.
- */
--static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){
--  UNUSED_PARAMETER(NotUsed);
--  assert((size_t)nBuf>=(sizeof(time_t)+sizeof(int)));
-+static int unixOpenSharedMemory(unixFile *pDbFd){
-+  struct unixShm *p = 0;          /* The connection to be opened */
-+  struct unixShmNode *pShmNode;   /* The underlying mmapped file */
-+  int rc;                         /* Result code */
-+  unixInodeInfo *pInode;          /* The inode of fd */
-+  char *zShmFilename;             /* Name of the file used for SHM */
-+  int nShmFilename;               /* Size of the SHM filename in bytes */
- 
--  /* We have to initialize zBuf to prevent valgrind from reporting
--  ** errors.  The reports issued by valgrind are incorrect - we would
--  ** prefer that the randomness be increased by making use of the
--  ** uninitialized space in zBuf - but valgrind errors tend to worry
--  ** some users.  Rather than argue, it seems easier just to initialize
--  ** the whole array and silence valgrind, even if that means less randomness
--  ** in the random seed.
--  **
--  ** When testing, initializing zBuf[] to zero is all we do.  That means
--  ** that we always use the same random number sequence.  This makes the
--  ** tests repeatable.
--  */
--  memset(zBuf, 0, nBuf);
--#if !defined(SQLITE_TEST)
--  {
--    int pid, fd, got;
--    fd = robust_open("/dev/urandom", O_RDONLY, 0);
--    if( fd<0 ){
--      time_t t;
--      time(&t);
--      memcpy(zBuf, &t, sizeof(t));
--      pid = getpid();
--      memcpy(&zBuf[sizeof(t)], &pid, sizeof(pid));
--      assert( sizeof(t)+sizeof(pid)<=(size_t)nBuf );
--      nBuf = sizeof(t) + sizeof(pid);
--    }else{
--      do{ got = osRead(fd, zBuf, nBuf); }while( got<0 && errno==EINTR );
--      robust_close(0, fd, __LINE__);
--    }
--  }
--#endif
--  return nBuf;
--}
-+  /* Allocate space for the new unixShm object. */
-+  p = sqlite3_malloc( sizeof(*p) );
-+  if( p==0 ) return SQLITE_NOMEM;
-+  memset(p, 0, sizeof(*p));
-+  assert( pDbFd->pShm==0 );
- 
-+  /* Check to see if a unixShmNode object already exists. Reuse an existing
-+  ** one if present. Create a new one if necessary.
-+  */
-+  unixEnterMutex();
-+  pInode = pDbFd->pInode;
-+  pShmNode = pInode->pShmNode;
-+  if( pShmNode==0 ){
-+    struct stat sStat;                 /* fstat() info for database file */
- 
--/*
--** Sleep for a little while.  Return the amount of time slept.
--** The argument is the number of microseconds we want to sleep.
--** The return value is the number of microseconds of sleep actually
--** requested from the underlying operating system, a number which
--** might be greater than or equal to the argument, but not less
--** than the argument.
--*/
--static int unixSleep(sqlite3_vfs *NotUsed, int microseconds){
--#if OS_VXWORKS
--  struct timespec sp;
-+    /* 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
-+    ** with the same permissions.
-+    */
-+    if( osFstat(pDbFd->h, &sStat) && pInode->bProcessLock==0 ){
-+      rc = SQLITE_IOERR_FSTAT;
-+      goto shm_open_err;
-+    }
- 
--  sp.tv_sec = microseconds / 1000000;
--  sp.tv_nsec = (microseconds % 1000000) * 1000;
--  nanosleep(&sp, NULL);
--  UNUSED_PARAMETER(NotUsed);
--  return microseconds;
--#elif defined(HAVE_USLEEP) && HAVE_USLEEP
--  usleep(microseconds);
--  UNUSED_PARAMETER(NotUsed);
--  return microseconds;
-+#ifdef SQLITE_SHM_DIRECTORY
-+    nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 31;
- #else
--  int seconds = (microseconds+999999)/1000000;
--  sleep(seconds);
--  UNUSED_PARAMETER(NotUsed);
--  return seconds*1000000;
-+    nShmFilename = 6 + (int)strlen(pDbFd->zPath);
- #endif
--}
-+    pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nShmFilename );
-+    if( pShmNode==0 ){
-+      rc = SQLITE_NOMEM;
-+      goto shm_open_err;
-+    }
-+    memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename);
-+    zShmFilename = pShmNode->zFilename = (char*)&pShmNode[1];
-+#ifdef SQLITE_SHM_DIRECTORY
-+    sqlite3_snprintf(nShmFilename, zShmFilename, 
-+                     SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x",
-+                     (u32)sStat.st_ino, (u32)sStat.st_dev);
-+#else
-+    sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", pDbFd->zPath);
-+    sqlite3FileSuffix3(pDbFd->zPath, zShmFilename);
-+#endif
-+    pShmNode->h = -1;
-+    pDbFd->pInode->pShmNode = pShmNode;
-+    pShmNode->pInode = pDbFd->pInode;
-+    pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
-+    if( pShmNode->mutex==0 ){
-+      rc = SQLITE_NOMEM;
-+      goto shm_open_err;
-+    }
-+
-+    if( pInode->bProcessLock==0 ){
-+      int openFlags = O_RDWR | O_CREAT;
-+      if( sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
-+        openFlags = O_RDONLY;
-+        pShmNode->isReadonly = 1;
-+      }
-+      pShmNode->h = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777));
-+      if( pShmNode->h<0 ){
-+        rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
-+        goto shm_open_err;
-+      }
-+
-+      /* If this process is running as root, make sure that the SHM file
-+      ** is owned by the same user that owns the original database.  Otherwise,
-+      ** the original owner will not be able to connect.
-+      */
-+      osFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
-+  
-+      /* Check to see if another process is holding the dead-man switch.
-+      ** If not, truncate the file to zero length. 
-+      */
-+      rc = SQLITE_OK;
-+      if( unixShmSystemLock(pShmNode, 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);
-+      }
-+      if( rc ) goto shm_open_err;
-+    }
-+  }
- 
--/*
--** 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. */
-+  /* Make the new connection a child of the unixShmNode */
-+  p->pShmNode = pShmNode;
-+#ifdef SQLITE_DEBUG
-+  p->id = pShmNode->nextShmId++;
- #endif
-+  pShmNode->nRef++;
-+  pDbFd->pShm = p;
-+  unixLeaveMutex();
-+
-+  /* The reference count on pShmNode has already been incremented under
-+  ** the cover of the unixEnterMutex() mutex and the pointer from the
-+  ** new (struct unixShm) 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:
-+  unixShmPurge(pDbFd);       /* This call frees pShmNode if required */
-+  sqlite3_free(p);
-+  unixLeaveMutex();
-+  return rc;
-+}
- 
- /*
--** 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.
-+** 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.
- **
--** On success, return SQLITE_OK.  Return SQLITE_ERROR if the time and date 
--** cannot be found.
-+** If an error occurs, an error code is returned and *pp is set to NULL.
-+**
-+** Otherwise, if the bExtend 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 
-+** bExtend 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 unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){
--  static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
-+static int unixShmMap(
-+  sqlite3_file *fd,               /* Handle open on database file */
-+  int iRegion,                    /* Region to retrieve */
-+  int szRegion,                   /* Size of regions */
-+  int bExtend,                    /* True to extend file if necessary */
-+  void volatile **pp              /* OUT: Mapped memory */
-+){
-+  unixFile *pDbFd = (unixFile*)fd;
-+  unixShm *p;
-+  unixShmNode *pShmNode;
-   int rc = SQLITE_OK;
--#if defined(NO_GETTOD)
--  time_t t;
--  time(&t);
--  *piNow = ((sqlite3_int64)t)*1000 + unixEpoch;
--#elif OS_VXWORKS
--  struct timespec sNow;
--  clock_gettime(CLOCK_REALTIME, &sNow);
--  *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_nsec/1000000;
--#else
--  struct timeval sNow;
--  if( gettimeofday(&sNow, 0)==0 ){
--    *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000;
--  }else{
--    rc = SQLITE_ERROR;
-+
-+  /* If the shared-memory file has not yet been opened, open it now. */
-+  if( pDbFd->pShm==0 ){
-+    rc = unixOpenSharedMemory(pDbFd);
-+    if( rc!=SQLITE_OK ) return rc;
-   }
--#endif
- 
--#ifdef SQLITE_TEST
--  if( sqlite3_current_time ){
--    *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
-+  p = pDbFd->pShm;
-+  pShmNode = p->pShmNode;
-+  sqlite3_mutex_enter(pShmNode->mutex);
-+  assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
-+  assert( pShmNode->pInode==pDbFd->pInode );
-+  assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
-+  assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
-+
-+  if( pShmNode->nRegion<=iRegion ){
-+    char **apNew;                      /* New apRegion[] array */
-+    int nByte = (iRegion+1)*szRegion;  /* Minimum required file size */
-+    struct stat sStat;                 /* Used by fstat() */
-+
-+    pShmNode->szRegion = szRegion;
-+
-+    if( pShmNode->h>=0 ){
-+      /* 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).
-+      */
-+      if( osFstat(pShmNode->h, &sStat) ){
-+        rc = SQLITE_IOERR_SHMSIZE;
-+        goto shmpage_out;
-+      }
-+  
-+      if( sStat.st_size<nByte ){
-+        /* The requested memory region does not exist. If bExtend is set to
-+        ** false, exit early. *pp will be set to NULL and SQLITE_OK returned.
-+        */
-+        if( !bExtend ){
-+          goto shmpage_out;
-+        }
-+
-+        /* Alternatively, if bExtend is true, extend the file. Do this by
-+        ** writing a single byte to the end of each (OS) page being
-+        ** allocated or extended. Technically, we need only write to the
-+        ** last page in order to extend the file. But writing to all new
-+        ** pages forces the OS to allocate them immediately, which reduces
-+        ** the chances of SIGBUS while accessing the mapped region later on.
-+        */
-+        else{
-+          static const int pgsz = 4096;
-+          int iPg;
-+
-+          /* Write to the last byte of each newly allocated or extended page */
-+          assert( (nByte % pgsz)==0 );
-+          for(iPg=(sStat.st_size/pgsz); iPg<(nByte/pgsz); iPg++){
-+            if( seekAndWriteFd(pShmNode->h, iPg*pgsz + pgsz-1, "", 1, 0)!=1 ){
-+              const char *zFile = pShmNode->zFilename;
-+              rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile);
-+              goto shmpage_out;
-+            }
-+          }
-+        }
-+      }
-+    }
-+
-+    /* Map the requested memory region into this processes address space. */
-+    apNew = (char **)sqlite3_realloc(
-+        pShmNode->apRegion, (iRegion+1)*sizeof(char *)
-+    );
-+    if( !apNew ){
-+      rc = SQLITE_IOERR_NOMEM;
-+      goto shmpage_out;
-+    }
-+    pShmNode->apRegion = apNew;
-+    while(pShmNode->nRegion<=iRegion){
-+      void *pMem;
-+      if( pShmNode->h>=0 ){
-+        pMem = osMmap(0, szRegion,
-+            pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, 
-+            MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
-+        );
-+        if( pMem==MAP_FAILED ){
-+          rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename);
-+          goto shmpage_out;
-+        }
-+      }else{
-+        pMem = sqlite3_malloc(szRegion);
-+        if( pMem==0 ){
-+          rc = SQLITE_NOMEM;
-+          goto shmpage_out;
-+        }
-+        memset(pMem, 0, szRegion);
-+      }
-+      pShmNode->apRegion[pShmNode->nRegion] = pMem;
-+      pShmNode->nRegion++;
-+    }
-   }
--#endif
--  UNUSED_PARAMETER(NotUsed);
--  return rc;
--}
- 
--/*
--** 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.
--*/
--static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){
--  sqlite3_int64 i = 0;
--  int rc;
--  UNUSED_PARAMETER(NotUsed);
--  rc = unixCurrentTimeInt64(0, &i);
--  *prNow = i/86400000.0;
-+shmpage_out:
-+  if( pShmNode->nRegion>iRegion ){
-+    *pp = pShmNode->apRegion[iRegion];
-+  }else{
-+    *pp = 0;
-+  }
-+  if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY;
-+  sqlite3_mutex_leave(pShmNode->mutex);
-   return rc;
- }
- 
- /*
--** We added the xGetLastError() method with the intention of providing
--** better low-level error messages when operating-system problems come up
--** during SQLite operation.  But so far, none of that has been implemented
--** in the core.  So this routine is never called.  For now, it is merely
--** a place-holder.
--*/
--static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
--  UNUSED_PARAMETER(NotUsed);
--  UNUSED_PARAMETER(NotUsed2);
--  UNUSED_PARAMETER(NotUsed3);
--  return 0;
--}
--
--
--/*
--************************ End of sqlite3_vfs methods ***************************
--******************************************************************************/
--
--/******************************************************************************
--************************** Begin Proxy Locking ********************************
--**
--** Proxy locking is a "uber-locking-method" in this sense:  It uses the
--** other locking methods on secondary lock files.  Proxy locking is a
--** meta-layer over top of the primitive locking implemented above.  For
--** this reason, the division that implements of proxy locking is deferred
--** until late in the file (here) after all of the other I/O methods have
--** been defined - so that the primitive locking methods are available
--** as services to help with the implementation of proxy locking.
--**
--****
--**
--** The default locking schemes in SQLite use byte-range locks on the
--** database file to coordinate safe, concurrent access by multiple readers
--** and writers [http://sqlite.org/lockingv3.html].  The five file locking
--** states (UNLOCKED, PENDING, SHARED, RESERVED, EXCLUSIVE) are implemented
--** as POSIX read & write locks over fixed set of locations (via fsctl),
--** on AFP and SMB only exclusive byte-range locks are available via fsctl
--** with _IOWR('z', 23, struct ByteRangeLockPB2) to track the same 5 states.
--** To simulate a F_RDLCK on the shared range, on AFP a randomly selected
--** address in the shared range is taken for a SHARED lock, the entire
--** shared range is taken for an EXCLUSIVE lock):
--**
--**      PENDING_BYTE        0x40000000
--**      RESERVED_BYTE       0x40000001
--**      SHARED_RANGE        0x40000002 -> 0x40000200
--**
--** This works well on the local file system, but shows a nearly 100x
--** slowdown in read performance on AFP because the AFP client disables
--** the read cache when byte-range locks are present.  Enabling the read
--** cache exposes a cache coherency problem that is present on all OS X
--** supported network file systems.  NFS and AFP both observe the
--** close-to-open semantics for ensuring cache coherency
--** [http://nfs.sourceforge.net/#faq_a8], which does not effectively
--** address the requirements for concurrent database access by multiple
--** readers and writers
--** [http://www.nabble.com/SQLite-on-NFS-cache-coherency-td15655701.html].
--**
--** To address the performance and cache coherency issues, proxy file locking
--** changes the way database access is controlled by limiting access to a
--** single host at a time and moving file locks off of the database file
--** and onto a proxy file on the local file system.  
--**
--**
--** Using proxy locks
--** -----------------
--**
--** C APIs
--**
--**  sqlite3_file_control(db, dbname, SQLITE_SET_LOCKPROXYFILE,
--**                       <proxy_path> | ":auto:");
--**  sqlite3_file_control(db, dbname, SQLITE_GET_LOCKPROXYFILE, &<proxy_path>);
--**
--**
--** SQL pragmas
--**
--**  PRAGMA [database.]lock_proxy_file=<proxy_path> | :auto:
--**  PRAGMA [database.]lock_proxy_file
--**
--** Specifying ":auto:" means that if there is a conch file with a matching
--** host ID in it, the proxy path in the conch file will be used, otherwise
--** a proxy path based on the user's temp dir
--** (via confstr(_CS_DARWIN_USER_TEMP_DIR,...)) will be used and the
--** actual proxy file name is generated from the name and path of the
--** database file.  For example:
--**
--**       For database path "/Users/me/foo.db" 
--**       The lock path will be "<tmpdir>/sqliteplocks/_Users_me_foo.db:auto:")
--**
--** Once a lock proxy is configured for a database connection, it can not
--** be removed, however it may be switched to a different proxy path via
--** the above APIs (assuming the conch file is not being held by another
--** connection or process). 
--**
--**
--** How proxy locking works
--** -----------------------
--**
--** Proxy file locking relies primarily on two new supporting files: 
--**
--**   *  conch file to limit access to the database file to a single host
--**      at a time
--**
--**   *  proxy file to act as a proxy for the advisory locks normally
--**      taken on the database
--**
--** The conch file - to use a proxy file, sqlite must first "hold the conch"
--** by taking an sqlite-style shared lock on the conch file, reading the
--** contents and comparing the host's unique host ID (see below) and lock
--** 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
--** 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
--** is held by another process (with a shared lock), the exclusive lock
--** will fail and SQLITE_BUSY is returned.
--**
--** The proxy file - a single-byte file used for all advisory file locks
--** normally taken on the database file.   This allows for safe sharing
--** of the database file for multiple readers and writers on the same
--** host (the conch ensures that they all use the same local lock file).
--**
--** Requesting the lock proxy does not immediately take the conch, it is
--** only taken when the first request to lock database file is made.  
--** This matches the semantics of the traditional locking behavior, where
--** opening a connection to a database file does not take a lock on it.
--** The shared lock and an open file descriptor are maintained until 
--** the connection to the database is closed. 
--**
--** The proxy file and the lock file are never deleted so they only need
--** to be created the first time they are used.
--**
--** Configuration options
--** ---------------------
--**
--**  SQLITE_PREFER_PROXY_LOCKING
--**
--**       Database files accessed on non-local file systems are
--**       automatically configured for proxy locking, lock files are
--**       named automatically using the same logic as
--**       PRAGMA lock_proxy_file=":auto:"
--**    
--**  SQLITE_PROXY_DEBUG
--**
--**       Enables the logging of error messages during host id file
--**       retrieval and creation
--**
--**  LOCKPROXYDIR
--**
--**       Overrides the default directory used for lock proxy files that
--**       are named automatically via the ":auto:" setting
--**
--**  SQLITE_DEFAULT_PROXYDIR_PERMISSIONS
-+** Change the lock state for a shared-memory segment.
- **
--**       Permissions to use when creating a directory for storing the
--**       lock proxy files, only used when LOCKPROXYDIR is not set.
--**    
--**    
--** As mentioned above, when compiled with SQLITE_PREFER_PROXY_LOCKING,
--** 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
--** sqlite_file_control API is not affected by SQLITE_FORCE_PROXY_LOCKING).
-+** Note that the relationship between SHAREd and EXCLUSIVE locks is a little
-+** different here than in posix.  In xShmLock(), one can go from unlocked
-+** to shared and back or from unlocked to exclusive and back.  But one may
-+** not go from shared to exclusive or from exclusive to shared.
- */
-+static int unixShmLock(
-+  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 */
-+){
-+  unixFile *pDbFd = (unixFile*)fd;      /* Connection holding shared memory */
-+  unixShm *p = pDbFd->pShm;             /* The shared memory being locked */
-+  unixShm *pX;                          /* For looping over all siblings */
-+  unixShmNode *pShmNode = p->pShmNode;  /* The underlying file iNode */
-+  int rc = SQLITE_OK;                   /* Result code */
-+  u16 mask;                             /* Mask of locks to take or release */
- 
--/*
--** Proxy locking is only available on MacOSX 
--*/
--#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
-+  assert( pShmNode==pDbFd->pInode->pShmNode );
-+  assert( pShmNode->pInode==pDbFd->pInode );
-+  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 );
-+  assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
-+  assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
- 
--/*
--** The proxyLockingContext has the path and file structures for the remote 
--** and local proxy files in it
--*/
--typedef struct proxyLockingContext proxyLockingContext;
--struct proxyLockingContext {
--  unixFile *conchFile;         /* Open conch file */
--  char *conchFilePath;         /* Name of the conch file */
--  unixFile *lockProxy;         /* Open proxy lock file */
--  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 */
--  void *oldLockingContext;     /* Original lockingcontext to restore on close */
--  sqlite3_io_methods const *pOldMethod;     /* Original I/O methods for close */
--};
-+  mask = (1<<(ofst+n)) - (1<<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 */
- 
--/* 
--** The proxy lock file path for the database at dbPath is written into lPath, 
--** which must point to valid, writable memory large enough for a maxLen length
--** file path. 
--*/
--static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){
--  int len;
--  int dbLen;
--  int i;
-+    /* 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;
-+    }
- 
--#ifdef LOCKPROXYDIR
--  len = strlcpy(lPath, LOCKPROXYDIR, maxLen);
--#else
--# ifdef _CS_DARWIN_USER_TEMP_DIR
--  {
--    if( !confstr(_CS_DARWIN_USER_TEMP_DIR, lPath, maxLen) ){
--      OSTRACE(("GETLOCKPATH  failed %s errno=%d pid=%d\n",
--               lPath, errno, getpid()));
--      return SQLITE_IOERR_LOCK;
-+    /* Unlock the system-level locks */
-+    if( (mask & allMask)==0 ){
-+      rc = unixShmSystemLock(pShmNode, F_UNLCK, ofst+UNIX_SHM_BASE, n);
-+    }else{
-+      rc = SQLITE_OK;
-     }
--    len = strlcat(lPath, "sqliteplocks", maxLen);    
--  }
--# else
--  len = strlcpy(lPath, "/tmp/", maxLen);
--# endif
--#endif
- 
--  if( lPath[len-1]!='/' ){
--    len = strlcat(lPath, "/", maxLen);
--  }
--  
--  /* transform the db path to a unique cache name */
--  dbLen = (int)strlen(dbPath);
--  for( i=0; i<dbLen && (i+len+7)<(int)maxLen; i++){
--    char c = dbPath[i];
--    lPath[i+len] = (c=='/')?'_':c;
--  }
--  lPath[i+len]='\0';
--  strlcat(lPath, ":auto:", maxLen);
--  OSTRACE(("GETLOCKPATH  proxy lock path=%s pid=%d\n", lPath, getpid()));
--  return SQLITE_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" */
- 
--/* 
-- ** Creates the lock file and any missing directories in lockPath
-- */
--static int proxyCreateLockPath(const char *lockPath){
--  int i, len;
--  char buf[MAXPATHLEN];
--  int start = 0;
--  
--  assert(lockPath!=NULL);
--  /* try to create all the intermediate directories */
--  len = (int)strlen(lockPath);
--  buf[0] = lockPath[0];
--  for( i=1; i<len; i++ ){
--    if( lockPath[i] == '/' && (i - start > 0) ){
--      /* only mkdir if leaf dir != "." or "/" or ".." */
--      if( i-start>2 || (i-start==1 && buf[start] != '.' && buf[start] != '/') 
--         || (i-start==2 && buf[start] != '.' && buf[start+1] != '.') ){
--        buf[i]='\0';
--        if( osMkdir(buf, SQLITE_DEFAULT_PROXYDIR_PERMISSIONS) ){
--          int err=errno;
--          if( err!=EEXIST ) {
--            OSTRACE(("CREATELOCKPATH  FAILED creating %s, "
--                     "'%s' proxy lock path=%s pid=%d\n",
--                     buf, strerror(err), lockPath, getpid()));
--            return err;
--          }
--        }
-+    /* 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;
-       }
--      start=i+1;
-+      allShared |= pX->sharedMask;
-     }
--    buf[i] = lockPath[i];
--  }
--  OSTRACE(("CREATELOCKPATH  proxy lock path=%s pid=%d\n", lockPath, getpid()));
--  return 0;
--}
--
--/*
--** Create a new VFS file descriptor (stored in memory obtained from
--** sqlite3_malloc) and open the file named "path" in the file descriptor.
--**
--** The caller is responsible not only for closing the file descriptor
--** but also for freeing the memory associated with the file descriptor.
--*/
--static int proxyCreateUnixFile(
--    const char *path,        /* path for the new unixFile */
--    unixFile **ppFile,       /* unixFile created and returned by ref */
--    int islockfile           /* if non zero missing dirs will be created */
--) {
--  int fd = -1;
--  unixFile *pNew;
--  int rc = SQLITE_OK;
--  int openFlags = O_RDWR | O_CREAT;
--  sqlite3_vfs dummyVfs;
--  int terrno = 0;
--  UnixUnusedFd *pUnused = NULL;
- 
--  /* 1. first try to open/create the file
--  ** 2. if that fails, and this is a lock file (not-conch), try creating
--  ** the parent directories and then try again.
--  ** 3. if that fails, try to open the file read-only
--  ** otherwise return BUSY (if lock file) or CANTOPEN for the conch file
--  */
--  pUnused = findReusableFd(path, openFlags);
--  if( pUnused ){
--    fd = pUnused->fd;
--  }else{
--    pUnused = sqlite3_malloc(sizeof(*pUnused));
--    if( !pUnused ){
--      return SQLITE_NOMEM;
--    }
--  }
--  if( fd<0 ){
--    fd = robust_open(path, openFlags, 0);
--    terrno = errno;
--    if( fd<0 && errno==ENOENT && islockfile ){
--      if( proxyCreateLockPath(path) == SQLITE_OK ){
--        fd = robust_open(path, openFlags, 0);
-+    /* 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);
-+      }else{
-+        rc = SQLITE_OK;
-       }
-     }
--  }
--  if( fd<0 ){
--    openFlags = O_RDONLY;
--    fd = robust_open(path, openFlags, 0);
--    terrno = errno;
--  }
--  if( fd<0 ){
--    if( islockfile ){
--      return SQLITE_BUSY;
-+
-+    /* Get the local shared locks */
-+    if( rc==SQLITE_OK ){
-+      p->sharedMask |= mask;
-     }
--    switch (terrno) {
--      case EACCES:
--        return SQLITE_PERM;
--      case EIO: 
--        return SQLITE_IOERR_LOCK; /* even though it is the conch */
--      default:
--        return SQLITE_CANTOPEN_BKPT;
-+  }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;
-+      }
-     }
--  }
--  
--  pNew = (unixFile *)sqlite3_malloc(sizeof(*pNew));
--  if( pNew==NULL ){
--    rc = SQLITE_NOMEM;
--    goto end_create_proxy;
--  }
--  memset(pNew, 0, sizeof(unixFile));
--  pNew->openFlags = openFlags;
--  memset(&dummyVfs, 0, sizeof(dummyVfs));
--  dummyVfs.pAppData = (void*)&autolockIoFinder;
--  dummyVfs.zName = "dummy";
--  pUnused->fd = fd;
--  pUnused->flags = openFlags;
--  pNew->pUnused = pUnused;
-   
--  rc = fillInUnixFile(&dummyVfs, fd, (sqlite3_file*)pNew, path, 0);
--  if( rc==SQLITE_OK ){
--    *ppFile = pNew;
--    return SQLITE_OK;
-+    /* Get the exclusive locks at the system level.  Then if successful
-+    ** also mark the local connection as being locked.
-+    */
-+    if( rc==SQLITE_OK ){
-+      rc = unixShmSystemLock(pShmNode, F_WRLCK, ofst+UNIX_SHM_BASE, n);
-+      if( rc==SQLITE_OK ){
-+        assert( (p->sharedMask & mask)==0 );
-+        p->exclMask |= mask;
-+      }
-+    }
-   }
--end_create_proxy:    
--  robust_close(pNew, fd, __LINE__);
--  sqlite3_free(pNew);
--  sqlite3_free(pUnused);
-+  sqlite3_mutex_leave(pShmNode->mutex);
-+  OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
-+           p->id, getpid(), p->sharedMask, p->exclMask));
-   return rc;
- }
- 
--#ifdef SQLITE_TEST
--/* simulate multiple hosts by creating unique hostid file paths */
--SQLITE_API int sqlite3_hostid_num = 0;
--#endif
-+/*
-+** 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.
-+*/
-+static void unixShmBarrier(
-+  sqlite3_file *fd                /* Database file holding the shared memory */
-+){
-+  UNUSED_PARAMETER(fd);
-+  unixEnterMutex();
-+  unixLeaveMutex();
-+}
- 
--#define PROXY_HOSTIDLEN    16  /* conch file host id length */
-+/*
-+** Close a connection to shared-memory.  Delete the underlying 
-+** storage if deleteFlag is true.
-+**
-+** If there is no shared memory associated with the connection then this
-+** routine is a harmless no-op.
-+*/
-+static int unixShmUnmap(
-+  sqlite3_file *fd,               /* The underlying database file */
-+  int deleteFlag                  /* Delete shared-memory if true */
-+){
-+  unixShm *p;                     /* The connection to be closed */
-+  unixShmNode *pShmNode;          /* The underlying shared-memory file */
-+  unixShm **pp;                   /* For looping over sibling connections */
-+  unixFile *pDbFd;                /* The underlying database file */
- 
--/* Not always defined in the headers as it ought to be */
--extern int gethostuuid(uuid_t id, const struct timespec *wait);
-+  pDbFd = (unixFile*)fd;
-+  p = pDbFd->pShm;
-+  if( p==0 ) return SQLITE_OK;
-+  pShmNode = p->pShmNode;
- 
--/* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN 
--** bytes of writable memory.
--*/
--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
--  {
--    static const struct timespec timeout = {1, 0}; /* 1 sec timeout */
--    if( gethostuuid(pHostID, &timeout) ){
--      int err = errno;
--      if( pError ){
--        *pError = err;
--      }
--      return SQLITE_IOERR;
--    }
-+  assert( pShmNode==pDbFd->pInode->pShmNode );
-+  assert( pShmNode->pInode==pDbFd->pInode );
-+
-+  /* 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;
-+
-+  /* 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 */
-+  unixEnterMutex();
-+  assert( pShmNode->nRef>0 );
-+  pShmNode->nRef--;
-+  if( pShmNode->nRef==0 ){
-+    if( deleteFlag && pShmNode->h>=0 ) osUnlink(pShmNode->zFilename);
-+    unixShmPurge(pDbFd);
-   }
-+  unixLeaveMutex();
-+
-+  return SQLITE_OK;
-+}
-+
-+
- #else
--  UNUSED_PARAMETER(pError);
--#endif
--#ifdef SQLITE_TEST
--  /* simulate multiple hosts by creating unique hostid file paths */
--  if( sqlite3_hostid_num != 0){
--    pHostID[0] = (char)(pHostID[0] + (char)(sqlite3_hostid_num & 0xFF));
-+# define unixShmMap     0
-+# define unixShmLock    0
-+# define unixShmBarrier 0
-+# define unixShmUnmap   0
-+#endif /* #ifndef SQLITE_OMIT_WAL */
-+
-+/*
-+** If it is currently memory mapped, unmap file pFd.
-+*/
-+static void unixUnmapfile(unixFile *pFd){
-+  assert( pFd->nFetchOut==0 );
-+#if SQLITE_MAX_MMAP_SIZE>0
-+  if( pFd->pMapRegion ){
-+    osMunmap(pFd->pMapRegion, pFd->mmapSizeActual);
-+    pFd->pMapRegion = 0;
-+    pFd->mmapSize = 0;
-+    pFd->mmapSizeActual = 0;
-   }
- #endif
--  
--  return SQLITE_OK;
- }
- 
--/* The conch file contains the header, host id and lock file path
-- */
--#define PROXY_CONCHVERSION 2   /* 1-byte header, 16-byte host id, path */
--#define PROXY_HEADERLEN    1   /* conch file header length */
--#define PROXY_PATHINDEX    (PROXY_HEADERLEN+PROXY_HOSTIDLEN)
--#define PROXY_MAXCONCHLEN  (PROXY_HEADERLEN+PROXY_HOSTIDLEN+MAXPATHLEN)
-+#if SQLITE_MAX_MMAP_SIZE>0
-+/*
-+** Return the system page size.
-+*/
-+static int unixGetPagesize(void){
-+#if HAVE_MREMAP
-+  return 512;
-+#elif defined(_BSD_SOURCE)
-+  return getpagesize();
-+#else
-+  return (int)sysconf(_SC_PAGESIZE);
-+#endif
-+}
-+#endif /* SQLITE_MAX_MMAP_SIZE>0 */
- 
--/* 
--** Takes an open conch file, copies the contents to a new path and then moves 
--** it back.  The newly created file's file descriptor is assigned to the
--** conch file structure and finally the original conch file descriptor is 
--** closed.  Returns zero if successful.
-+#if SQLITE_MAX_MMAP_SIZE>0
-+/*
-+** Attempt to set the size of the memory mapping maintained by file 
-+** descriptor pFd to nNew bytes. Any existing mapping is discarded.
-+**
-+** If successful, this function sets the following variables:
-+**
-+**       unixFile.pMapRegion
-+**       unixFile.mmapSize
-+**       unixFile.mmapSizeActual
-+**
-+** If unsuccessful, an error message is logged via sqlite3_log() and
-+** the three variables above are zeroed. In this case SQLite should
-+** continue accessing the database using the xRead() and xWrite()
-+** methods.
- */
--static int proxyBreakConchLock(unixFile *pFile, uuid_t myHostID){
--  proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; 
--  unixFile *conchFile = pCtx->conchFile;
--  char tPath[MAXPATHLEN];
--  char buf[PROXY_MAXCONCHLEN];
--  char *cPath = pCtx->conchFilePath;
--  size_t readLen = 0;
--  size_t pathLen = 0;
--  char errmsg[64] = "";
--  int fd = -1;
--  int rc = -1;
--  UNUSED_PARAMETER(myHostID);
-+static void unixRemapfile(
-+  unixFile *pFd,                  /* File descriptor object */
-+  i64 nNew                        /* Required mapping size */
-+){
-+  const char *zErr = "mmap";
-+  int h = pFd->h;                      /* File descriptor open on db file */
-+  u8 *pOrig = (u8 *)pFd->pMapRegion;   /* Pointer to current file mapping */
-+  i64 nOrig = pFd->mmapSizeActual;     /* Size of pOrig region in bytes */
-+  u8 *pNew = 0;                        /* Location of new mapping */
-+  int flags = PROT_READ;               /* Flags to pass to mmap() */
- 
--  /* create a new path by replace the trailing '-conch' with '-break' */
--  pathLen = strlcpy(tPath, cPath, MAXPATHLEN);
--  if( pathLen>MAXPATHLEN || pathLen<6 || 
--     (strlcpy(&tPath[pathLen-5], "break", 6) != 5) ){
--    sqlite3_snprintf(sizeof(errmsg),errmsg,"path error (len %d)",(int)pathLen);
--    goto end_breaklock;
--  }
--  /* read the conch content */
--  readLen = osPread(conchFile->h, buf, PROXY_MAXCONCHLEN, 0);
--  if( readLen<PROXY_PATHINDEX ){
--    sqlite3_snprintf(sizeof(errmsg),errmsg,"read error (len %d)",(int)readLen);
--    goto end_breaklock;
--  }
--  /* write it out to the temporary break file */
--  fd = robust_open(tPath, (O_RDWR|O_CREAT|O_EXCL), 0);
--  if( fd<0 ){
--    sqlite3_snprintf(sizeof(errmsg), errmsg, "create failed (%d)", errno);
--    goto end_breaklock;
--  }
--  if( osPwrite(fd, buf, readLen, 0) != (ssize_t)readLen ){
--    sqlite3_snprintf(sizeof(errmsg), errmsg, "write failed (%d)", errno);
--    goto end_breaklock;
--  }
--  if( rename(tPath, cPath) ){
--    sqlite3_snprintf(sizeof(errmsg), errmsg, "rename failed (%d)", errno);
--    goto end_breaklock;
--  }
--  rc = 0;
--  fprintf(stderr, "broke stale lock on %s\n", cPath);
--  robust_close(pFile, conchFile->h, __LINE__);
--  conchFile->h = fd;
--  conchFile->openFlags = O_RDWR | O_CREAT;
-+  assert( pFd->nFetchOut==0 );
-+  assert( nNew>pFd->mmapSize );
-+  assert( nNew<=pFd->mmapSizeMax );
-+  assert( nNew>0 );
-+  assert( pFd->mmapSizeActual>=pFd->mmapSize );
-+  assert( MAP_FAILED!=0 );
- 
--end_breaklock:
--  if( rc ){
--    if( fd>=0 ){
--      osUnlink(tPath);
--      robust_close(pFile, fd, __LINE__);
-+  if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE;
-+
-+  if( pOrig ){
-+    const int szSyspage = unixGetPagesize();
-+    i64 nReuse = (pFd->mmapSize & ~(szSyspage-1));
-+    u8 *pReq = &pOrig[nReuse];
-+
-+    /* Unmap any pages of the existing mapping that cannot be reused. */
-+    if( nReuse!=nOrig ){
-+      osMunmap(pReq, nOrig-nReuse);
-     }
--    fprintf(stderr, "failed to break stale lock on %s, %s\n", cPath, errmsg);
--  }
--  return rc;
--}
- 
--/* Take the requested lock on the conch file and break a stale lock if the 
--** host id matches.
--*/
--static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){
--  proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; 
--  unixFile *conchFile = pCtx->conchFile;
--  int rc = SQLITE_OK;
--  int nTries = 0;
--  struct timespec conchModTime;
--  
--  memset(&conchModTime, 0, sizeof(conchModTime));
--  do {
--    rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType);
--    nTries ++;
--    if( rc==SQLITE_BUSY ){
--      /* If the lock failed (busy):
--       * 1st try: get the mod time of the conch, wait 0.5s and try again. 
--       * 2nd try: fail if the mod time changed or host id is different, wait 
--       *           10 sec and try again
--       * 3rd try: break the lock unless the mod time has changed.
--       */
--      struct stat buf;
--      if( osFstat(conchFile->h, &buf) ){
--        pFile->lastErrno = errno;
--        return SQLITE_IOERR_LOCK;
--      }
--      
--      if( nTries==1 ){
--        conchModTime = buf.st_mtimespec;
--        usleep(500000); /* wait 0.5 sec and try the lock again*/
--        continue;  
-+#if HAVE_MREMAP
-+    pNew = osMremap(pOrig, nReuse, nNew, MREMAP_MAYMOVE);
-+    zErr = "mremap";
-+#else
-+    pNew = osMmap(pReq, nNew-nReuse, flags, MAP_SHARED, h, nReuse);
-+    if( pNew!=MAP_FAILED ){
-+      if( pNew!=pReq ){
-+        osMunmap(pNew, nNew - nReuse);
-+        pNew = 0;
-+      }else{
-+        pNew = pOrig;
-       }
-+    }
-+#endif
- 
--      assert( nTries>1 );
--      if( conchModTime.tv_sec != buf.st_mtimespec.tv_sec || 
--         conchModTime.tv_nsec != buf.st_mtimespec.tv_nsec ){
--        return SQLITE_BUSY;
--      }
--      
--      if( nTries==2 ){  
--        char tBuf[PROXY_MAXCONCHLEN];
--        int len = osPread(conchFile->h, tBuf, PROXY_MAXCONCHLEN, 0);
--        if( len<0 ){
--          pFile->lastErrno = errno;
--          return SQLITE_IOERR_LOCK;
--        }
--        if( len>PROXY_PATHINDEX && tBuf[0]==(char)PROXY_CONCHVERSION){
--          /* don't break the lock if the host id doesn't match */
--          if( 0!=memcmp(&tBuf[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN) ){
--            return SQLITE_BUSY;
--          }
--        }else{
--          /* don't break the lock on short read or a version mismatch */
--          return SQLITE_BUSY;
--        }
--        usleep(10000000); /* wait 10 sec and try the lock again */
--        continue; 
--      }
--      
--      assert( nTries==3 );
--      if( 0==proxyBreakConchLock(pFile, myHostID) ){
--        rc = SQLITE_OK;
--        if( lockType==EXCLUSIVE_LOCK ){
--          rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK);          
--        }
--        if( !rc ){
--          rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType);
--        }
--      }
-+    /* The attempt to extend the existing mapping failed. Free it. */
-+    if( pNew==MAP_FAILED || pNew==0 ){
-+      osMunmap(pOrig, nReuse);
-     }
--  } while( rc==SQLITE_BUSY && nTries<3 );
--  
--  return rc;
-+  }
-+
-+  /* If pNew is still NULL, try to create an entirely new mapping. */
-+  if( pNew==0 ){
-+    pNew = osMmap(0, nNew, flags, MAP_SHARED, h, 0);
-+  }
-+
-+  if( pNew==MAP_FAILED ){
-+    pNew = 0;
-+    nNew = 0;
-+    unixLogError(SQLITE_OK, zErr, pFd->zPath);
-+
-+    /* If the mmap() above failed, assume that all subsequent mmap() calls
-+    ** will probably fail too. Fall back to using xRead/xWrite exclusively
-+    ** in this case.  */
-+    pFd->mmapSizeMax = 0;
-+  }
-+  pFd->pMapRegion = (void *)pNew;
-+  pFd->mmapSize = pFd->mmapSizeActual = nNew;
- }
-+#endif
- 
--/* Takes the conch by taking a shared lock and read the contents conch, if 
--** lockPath is non-NULL, the host ID and lock file path must match.  A NULL 
--** lockPath means that the lockPath in the conch file will be used if the 
--** host IDs match, or a new lock path will be generated automatically 
--** and written to the conch file.
-+/*
-+** 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_LIMIT, 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 int proxyTakeConch(unixFile *pFile){
--  proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; 
--  
--  if( pCtx->conchHeld!=0 ){
--    return SQLITE_OK;
--  }else{
--    unixFile *conchFile = pCtx->conchFile;
--    uuid_t myHostID;
--    int pError = 0;
--    char readBuf[PROXY_MAXCONCHLEN];
--    char lockPath[MAXPATHLEN];
--    char *tempLockPath = NULL;
--    int rc = SQLITE_OK;
--    int createConch = 0;
--    int hostIdMatch = 0;
--    int readLen = 0;
--    int tryOldLockPath = 0;
--    int forceNewLockPath = 0;
--    
--    OSTRACE(("TAKECONCH  %d for %s pid=%d\n", conchFile->h,
--             (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), getpid()));
--
--    rc = proxyGetHostID(myHostID, &pError);
--    if( (rc&0xff)==SQLITE_IOERR ){
--      pFile->lastErrno = pError;
--      goto end_takeconch;
--    }
--    rc = proxyConchLock(pFile, myHostID, SHARED_LOCK);
-+static int unixMapfile(unixFile *pFd, i64 nByte){
-+#if SQLITE_MAX_MMAP_SIZE>0
-+  i64 nMap = nByte;
-+  int rc;
-+
-+  assert( nMap>=0 || pFd->nFetchOut==0 );
-+  if( pFd->nFetchOut>0 ) return SQLITE_OK;
-+
-+  if( nMap<0 ){
-+    struct stat statbuf;          /* Low-level file information */
-+    rc = osFstat(pFd->h, &statbuf);
-     if( rc!=SQLITE_OK ){
--      goto end_takeconch;
-+      return SQLITE_IOERR_FSTAT;
-     }
--    /* read the existing conch file */
--    readLen = seekAndRead((unixFile*)conchFile, 0, readBuf, PROXY_MAXCONCHLEN);
--    if( readLen<0 ){
--      /* I/O error: lastErrno set by seekAndRead */
--      pFile->lastErrno = conchFile->lastErrno;
--      rc = SQLITE_IOERR_READ;
--      goto end_takeconch;
--    }else if( readLen<=(PROXY_HEADERLEN+PROXY_HOSTIDLEN) || 
--             readBuf[0]!=(char)PROXY_CONCHVERSION ){
--      /* a short read or version format mismatch means we need to create a new 
--      ** conch file. 
--      */
--      createConch = 1;
-+    nMap = statbuf.st_size;
-+  }
-+  if( nMap>pFd->mmapSizeMax ){
-+    nMap = pFd->mmapSizeMax;
-+  }
-+
-+  if( nMap!=pFd->mmapSize ){
-+    if( nMap>0 ){
-+      unixRemapfile(pFd, nMap);
-+    }else{
-+      unixUnmapfile(pFd);
-     }
--    /* if the host id matches and the lock path already exists in the conch
--    ** we'll try to use the path there, if we can't open that path, we'll 
--    ** retry with a new auto-generated path 
--    */
--    do { /* in case we need to try again for an :auto: named lock file */
-+  }
-+#endif
- 
--      if( !createConch && !forceNewLockPath ){
--        hostIdMatch = !memcmp(&readBuf[PROXY_HEADERLEN], myHostID, 
--                                  PROXY_HOSTIDLEN);
--        /* if the conch has data compare the contents */
--        if( !pCtx->lockProxyPath ){
--          /* for auto-named local lock file, just check the host ID and we'll
--           ** use the local lock file path that's already in there
--           */
--          if( hostIdMatch ){
--            size_t pathLen = (readLen - PROXY_PATHINDEX);
--            
--            if( pathLen>=MAXPATHLEN ){
--              pathLen=MAXPATHLEN-1;
--            }
--            memcpy(lockPath, &readBuf[PROXY_PATHINDEX], pathLen);
--            lockPath[pathLen] = 0;
--            tempLockPath = lockPath;
--            tryOldLockPath = 1;
--            /* create a copy of the lock path if the conch is taken */
--            goto end_takeconch;
--          }
--        }else if( hostIdMatch
--               && !strncmp(pCtx->lockProxyPath, &readBuf[PROXY_PATHINDEX],
--                           readLen-PROXY_PATHINDEX)
--        ){
--          /* conch host and lock path match */
--          goto end_takeconch; 
--        }
--      }
--      
--      /* if the conch isn't writable and doesn't match, we can't take it */
--      if( (conchFile->openFlags&O_RDWR) == 0 ){
--        rc = SQLITE_BUSY;
--        goto end_takeconch;
--      }
--      
--      /* either the conch didn't match or we need to create a new one */
--      if( !pCtx->lockProxyPath ){
--        proxyGetLockPath(pCtx->dbPath, lockPath, MAXPATHLEN);
--        tempLockPath = lockPath;
--        /* create a copy of the lock path _only_ if the conch is taken */
--      }
--      
--      /* update conch with host and path (this will fail if other process
--      ** has a shared lock already), if the host id matches, use the big
--      ** stick.
--      */
--      futimes(conchFile->h, NULL);
--      if( hostIdMatch && !createConch ){
--        if( conchFile->pInode && conchFile->pInode->nShared>1 ){
--          /* We are trying for an exclusive lock but another thread in this
--           ** same process is still holding a shared lock. */
--          rc = SQLITE_BUSY;
--        } else {          
--          rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK);
--        }
--      }else{
--        rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, EXCLUSIVE_LOCK);
--      }
--      if( rc==SQLITE_OK ){
--        char writeBuffer[PROXY_MAXCONCHLEN];
--        int writeSize = 0;
--        
--        writeBuffer[0] = (char)PROXY_CONCHVERSION;
--        memcpy(&writeBuffer[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN);
--        if( pCtx->lockProxyPath!=NULL ){
--          strlcpy(&writeBuffer[PROXY_PATHINDEX], pCtx->lockProxyPath, MAXPATHLEN);
--        }else{
--          strlcpy(&writeBuffer[PROXY_PATHINDEX], tempLockPath, MAXPATHLEN);
--        }
--        writeSize = PROXY_PATHINDEX + strlen(&writeBuffer[PROXY_PATHINDEX]);
--        robust_ftruncate(conchFile->h, writeSize);
--        rc = unixWrite((sqlite3_file *)conchFile, writeBuffer, writeSize, 0);
--        fsync(conchFile->h);
--        /* If we created a new conch file (not just updated the contents of a 
--         ** valid conch file), try to match the permissions of the database 
--         */
--        if( rc==SQLITE_OK && createConch ){
--          struct stat buf;
--          int err = osFstat(pFile->h, &buf);
--          if( err==0 ){
--            mode_t cmode = buf.st_mode&(S_IRUSR|S_IWUSR | S_IRGRP|S_IWGRP |
--                                        S_IROTH|S_IWOTH);
--            /* try to match the database file R/W permissions, ignore failure */
--#ifndef SQLITE_PROXY_DEBUG
--            osFchmod(conchFile->h, cmode);
--#else
--            do{
--              rc = osFchmod(conchFile->h, cmode);
--            }while( rc==(-1) && errno==EINTR );
--            if( rc!=0 ){
--              int code = errno;
--              fprintf(stderr, "fchmod %o FAILED with %d %s\n",
--                      cmode, code, strerror(code));
--            } else {
--              fprintf(stderr, "fchmod %o SUCCEDED\n",cmode);
--            }
--          }else{
--            int code = errno;
--            fprintf(stderr, "STAT FAILED[%d] with %d %s\n", 
--                    err, code, strerror(code));
-+  return SQLITE_OK;
-+}
-+
-+/*
-+** 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 unixUnfetch().
-+*/
-+static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
-+#if SQLITE_MAX_MMAP_SIZE>0
-+  unixFile *pFd = (unixFile *)fd;   /* The underlying database file */
- #endif
--          }
--        }
--      }
--      conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, SHARED_LOCK);
--      
--    end_takeconch:
--      OSTRACE(("TRANSPROXY: CLOSE  %d\n", pFile->h));
--      if( rc==SQLITE_OK && pFile->openFlags ){
--        int fd;
--        if( pFile->h>=0 ){
--          robust_close(pFile, pFile->h, __LINE__);
--        }
--        pFile->h = -1;
--        fd = robust_open(pCtx->dbPath, pFile->openFlags, 0);
--        OSTRACE(("TRANSPROXY: OPEN  %d\n", fd));
--        if( fd>=0 ){
--          pFile->h = fd;
--        }else{
--          rc=SQLITE_CANTOPEN_BKPT; /* SQLITE_BUSY? proxyTakeConch called
--           during locking */
--        }
--      }
--      if( rc==SQLITE_OK && !pCtx->lockProxy ){
--        char *path = tempLockPath ? tempLockPath : pCtx->lockProxyPath;
--        rc = proxyCreateUnixFile(path, &pCtx->lockProxy, 1);
--        if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM && tryOldLockPath ){
--          /* we couldn't create the proxy lock file with the old lock file path
--           ** so try again via auto-naming 
--           */
--          forceNewLockPath = 1;
--          tryOldLockPath = 0;
--          continue; /* go back to the do {} while start point, try again */
--        }
--      }
--      if( rc==SQLITE_OK ){
--        /* Need to make a copy of path if we extracted the value
--         ** from the conch file or the path was allocated on the stack
--         */
--        if( tempLockPath ){
--          pCtx->lockProxyPath = sqlite3DbStrDup(0, tempLockPath);
--          if( !pCtx->lockProxyPath ){
--            rc = SQLITE_NOMEM;
--          }
--        }
--      }
--      if( rc==SQLITE_OK ){
--        pCtx->conchHeld = 1;
--        
--        if( pCtx->lockProxy->pMethod == &afpIoMethods ){
--          afpLockingContext *afpCtx;
--          afpCtx = (afpLockingContext *)pCtx->lockProxy->lockingContext;
--          afpCtx->dbPath = pCtx->lockProxyPath;
--        }
--      } else {
--        conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK);
--      }
--      OSTRACE(("TAKECONCH  %d %s\n", conchFile->h,
--               rc==SQLITE_OK?"ok":"failed"));
--      return rc;
--    } while (1); /* in case we need to retry the :auto: lock file - 
--                 ** we should never get here except via the 'continue' call. */
-+  *pp = 0;
-+
-+#if SQLITE_MAX_MMAP_SIZE>0
-+  if( pFd->mmapSizeMax>0 ){
-+    if( pFd->pMapRegion==0 ){
-+      int rc = unixMapfile(pFd, -1);
-+      if( rc!=SQLITE_OK ) return rc;
-+    }
-+    if( pFd->mmapSize >= iOff+nAmt ){
-+      *pp = &((u8 *)pFd->pMapRegion)[iOff];
-+      pFd->nFetchOut++;
-+    }
-   }
-+#endif
-+  return SQLITE_OK;
- }
- 
- /*
--** If pFile holds a lock on a conch file, then release that lock.
-+** If the third argument is non-NULL, then this function releases a 
-+** reference obtained by an earlier call to unixFetch(). The second
-+** argument passed to this function must be the same as the corresponding
-+** argument that was passed to the unixFetch() 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 proxyReleaseConch(unixFile *pFile){
--  int rc = SQLITE_OK;         /* Subroutine return code */
--  proxyLockingContext *pCtx;  /* The locking context for the proxy lock */
--  unixFile *conchFile;        /* Name of the conch file */
-+static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){
-+  unixFile *pFd = (unixFile *)fd;   /* The underlying database file */
-+  UNUSED_PARAMETER(iOff);
- 
--  pCtx = (proxyLockingContext *)pFile->lockingContext;
--  conchFile = pCtx->conchFile;
--  OSTRACE(("RELEASECONCH  %d for %s pid=%d\n", conchFile->h,
--           (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), 
--           getpid()));
--  if( pCtx->conchHeld>0 ){
--    rc = conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK);
-+  /* 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] );
-+
-+  if( p ){
-+    pFd->nFetchOut--;
-+  }else{
-+    unixUnmapfile(pFd);
-   }
--  pCtx->conchHeld = 0;
--  OSTRACE(("RELEASECONCH  %d %s\n", conchFile->h,
--           (rc==SQLITE_OK ? "ok" : "failed")));
--  return rc;
-+
-+  assert( pFd->nFetchOut>=0 );
-+  return SQLITE_OK;
- }
- 
- /*
--** Given the name of a database file, compute the name of its conch file.
--** Store the conch filename in memory obtained from sqlite3_malloc().
--** Make *pConchPath point to the new name.  Return SQLITE_OK on success
--** or SQLITE_NOMEM if unable to obtain memory.
-+** Here ends the implementation of all sqlite3_file methods.
- **
--** The caller is responsible for ensuring that the allocated memory
--** space is eventually freed.
-+********************** End sqlite3_file Methods *******************************
-+******************************************************************************/
-+
-+/*
-+** This division contains definitions of sqlite3_io_methods objects that
-+** implement various file locking strategies.  It also contains definitions
-+** of "finder" functions.  A finder-function is used to locate the appropriate
-+** sqlite3_io_methods object for a particular database file.  The pAppData
-+** field of the sqlite3_vfs VFS objects are initialized to be pointers to
-+** the correct finder-function for that VFS.
- **
--** *pConchPath is set to NULL if a memory allocation error occurs.
-+** Most finder functions return a pointer to a fixed sqlite3_io_methods
-+** object.  The only interesting finder-function is autolockIoFinder, which
-+** looks at the filesystem type and tries to guess the best locking
-+** strategy from that.
-+**
-+** For finder-funtion F, two objects are created:
-+**
-+**    (1) The real finder-function named "FImpt()".
-+**
-+**    (2) A constant pointer to this function named just "F".
-+**
-+**
-+** A pointer to the F pointer is used as the pAppData value for VFS
-+** objects.  We have to do this instead of letting pAppData point
-+** directly at the finder-function since C90 rules prevent a void*
-+** from be cast into a function pointer.
-+**
-+**
-+** Each instance of this macro generates two objects:
-+**
-+**   *  A constant sqlite3_io_methods object call METHOD that has locking
-+**      methods CLOSE, LOCK, UNLOCK, CKRESLOCK.
-+**
-+**   *  An I/O method finder function called FINDER that returns a pointer
-+**      to the METHOD object in the previous bullet.
- */
--static int proxyCreateConchPathname(char *dbPath, char **pConchPath){
--  int i;                        /* Loop counter */
--  int len = (int)strlen(dbPath); /* Length of database filename - dbPath */
--  char *conchPath;              /* buffer in which to construct conch name */
-+#define IOMETHODS(FINDER, METHOD, VERSION, CLOSE, LOCK, UNLOCK, CKLOCK)      \
-+static const sqlite3_io_methods METHOD = {                                   \
-+   VERSION,                    /* iVersion */                                \
-+   CLOSE,                      /* xClose */                                  \
-+   unixRead,                   /* xRead */                                   \
-+   unixWrite,                  /* xWrite */                                  \
-+   unixTruncate,               /* xTruncate */                               \
-+   unixSync,                   /* xSync */                                   \
-+   unixFileSize,               /* xFileSize */                               \
-+   LOCK,                       /* xLock */                                   \
-+   UNLOCK,                     /* xUnlock */                                 \
-+   CKLOCK,                     /* xCheckReservedLock */                      \
-+   unixFileControl,            /* xFileControl */                            \
-+   unixSectorSize,             /* xSectorSize */                             \
-+   unixDeviceCharacteristics,  /* xDeviceCapabilities */                     \
-+   unixShmMap,                 /* xShmMap */                                 \
-+   unixShmLock,                /* xShmLock */                                \
-+   unixShmBarrier,             /* xShmBarrier */                             \
-+   unixShmUnmap,               /* xShmUnmap */                               \
-+   unixFetch,                  /* xFetch */                                  \
-+   unixUnfetch,                /* xUnfetch */                                \
-+};                                                                           \
-+static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){   \
-+  UNUSED_PARAMETER(z); UNUSED_PARAMETER(p);                                  \
-+  return &METHOD;                                                            \
-+}                                                                            \
-+static const sqlite3_io_methods *(*const FINDER)(const char*,unixFile *p)    \
-+    = FINDER##Impl;
- 
--  /* 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);
--  if( conchPath==0 ){
--    return SQLITE_NOMEM;
-+/*
-+** Here are all of the sqlite3_io_methods objects for each of the
-+** locking strategies.  Functions that return pointers to these methods
-+** are also created.
-+*/
-+IOMETHODS(
-+  posixIoFinder,            /* Finder function name */
-+  posixIoMethods,           /* sqlite3_io_methods object name */
-+  3,                        /* shared memory and mmap are enabled */
-+  unixClose,                /* xClose method */
-+  unixLock,                 /* xLock method */
-+  unixUnlock,               /* xUnlock method */
-+  unixCheckReservedLock     /* xCheckReservedLock method */
-+)
-+IOMETHODS(
-+  nolockIoFinder,           /* Finder function name */
-+  nolockIoMethods,          /* sqlite3_io_methods object name */
-+  1,                        /* shared memory is disabled */
-+  nolockClose,              /* xClose method */
-+  nolockLock,               /* xLock method */
-+  nolockUnlock,             /* xUnlock method */
-+  nolockCheckReservedLock   /* xCheckReservedLock method */
-+)
-+IOMETHODS(
-+  dotlockIoFinder,          /* Finder function name */
-+  dotlockIoMethods,         /* sqlite3_io_methods object name */
-+  1,                        /* shared memory is disabled */
-+  dotlockClose,             /* xClose method */
-+  dotlockLock,              /* xLock method */
-+  dotlockUnlock,            /* xUnlock method */
-+  dotlockCheckReservedLock  /* xCheckReservedLock method */
-+)
-+
-+#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
-+IOMETHODS(
-+  flockIoFinder,            /* Finder function name */
-+  flockIoMethods,           /* sqlite3_io_methods object name */
-+  1,                        /* shared memory is disabled */
-+  flockClose,               /* xClose method */
-+  flockLock,                /* xLock method */
-+  flockUnlock,              /* xUnlock method */
-+  flockCheckReservedLock    /* xCheckReservedLock method */
-+)
-+#endif
-+
-+#if OS_VXWORKS
-+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 */
-+)
-+#endif
-+
-+#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
-+IOMETHODS(
-+  afpIoFinder,              /* Finder function name */
-+  afpIoMethods,             /* sqlite3_io_methods object name */
-+  1,                        /* shared memory is disabled */
-+  afpClose,                 /* xClose method */
-+  afpLock,                  /* xLock method */
-+  afpUnlock,                /* xUnlock method */
-+  afpCheckReservedLock      /* xCheckReservedLock method */
-+)
-+#endif
-+
-+/*
-+** The proxy locking method is a "super-method" in the sense that it
-+** opens secondary file descriptors for the conch and lock files and
-+** it uses proxy, dot-file, AFP, and flock() locking methods on those
-+** secondary files.  For this reason, the division that implements
-+** proxy locking is located much further down in the file.  But we need
-+** to go ahead and define the sqlite3_io_methods and finder function
-+** for proxy locking here.  So we forward declare the I/O methods.
-+*/
-+#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
-+static int proxyClose(sqlite3_file*);
-+static int proxyLock(sqlite3_file*, int);
-+static int proxyUnlock(sqlite3_file*, int);
-+static int proxyCheckReservedLock(sqlite3_file*, int*);
-+IOMETHODS(
-+  proxyIoFinder,            /* Finder function name */
-+  proxyIoMethods,           /* sqlite3_io_methods object name */
-+  1,                        /* shared memory is disabled */
-+  proxyClose,               /* xClose method */
-+  proxyLock,                /* xLock method */
-+  proxyUnlock,              /* xUnlock method */
-+  proxyCheckReservedLock    /* xCheckReservedLock method */
-+)
-+#endif
-+
-+/* nfs lockd on OSX 10.3+ doesn't clear write locks when a read lock is set */
-+#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
-+IOMETHODS(
-+  nfsIoFinder,               /* Finder function name */
-+  nfsIoMethods,              /* sqlite3_io_methods object name */
-+  1,                         /* shared memory is disabled */
-+  unixClose,                 /* xClose method */
-+  unixLock,                  /* xLock method */
-+  nfsUnlock,                 /* xUnlock method */
-+  unixCheckReservedLock      /* xCheckReservedLock method */
-+)
-+#endif
-+
-+#if defined(__APPLE__) && 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 MacOSX only.
-+*/
-+static const sqlite3_io_methods *autolockIoFinderImpl(
-+  const char *filePath,    /* name of the database file */
-+  unixFile *pNew           /* open file object for the database file */
-+){
-+  static const struct Mapping {
-+    const char *zFilesystem;              /* Filesystem type name */
-+    const sqlite3_io_methods *pMethods;   /* Appropriate locking method */
-+  } aMap[] = {
-+    { "hfs",    &posixIoMethods },
-+    { "ufs",    &posixIoMethods },
-+    { "afpfs",  &afpIoMethods },
-+    { "smbfs",  &afpIoMethods },
-+    { "webdav", &nolockIoMethods },
-+    { 0, 0 }
-+  };
-+  int i;
-+  struct statfs fsInfo;
-+  struct flock lockInfo;
-+
-+  if( !filePath ){
-+    /* If filePath==NULL that means we are dealing with a transient file
-+    ** that does not need to be locked. */
-+    return &nolockIoMethods;
-   }
--  memcpy(conchPath, dbPath, len+1);
--  
--  /* now insert a "." before the last / character */
--  for( i=(len-1); i>=0; i-- ){
--    if( conchPath[i]=='/' ){
--      i++;
--      break;
-+  if( statfs(filePath, &fsInfo) != -1 ){
-+    if( fsInfo.f_flags & MNT_RDONLY ){
-+      return &nolockIoMethods;
-+    }
-+    for(i=0; aMap[i].zFilesystem; i++){
-+      if( strcmp(fsInfo.f_fstypename, aMap[i].zFilesystem)==0 ){
-+        return aMap[i].pMethods;
-+      }
-     }
-   }
--  conchPath[i]='.';
--  while ( i<len ){
--    conchPath[i+1]=dbPath[i];
--    i++;
--  }
--
--  /* append the "-conch" suffix to the file */
--  memcpy(&conchPath[i+1], "-conch", 7);
--  assert( (int)strlen(conchPath) == len+7 );
- 
--  return SQLITE_OK;
-+  /* Default case. Handles, amongst others, "nfs".
-+  ** Test byte-range lock using fcntl(). If the call succeeds, 
-+  ** assume that the file-system supports POSIX style locks. 
-+  */
-+  lockInfo.l_len = 1;
-+  lockInfo.l_start = 0;
-+  lockInfo.l_whence = SEEK_SET;
-+  lockInfo.l_type = F_RDLCK;
-+  if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) {
-+    if( strcmp(fsInfo.f_fstypename, "nfs")==0 ){
-+      return &nfsIoMethods;
-+    } else {
-+      return &posixIoMethods;
-+    }
-+  }else{
-+    return &dotlockIoMethods;
-+  }
- }
-+static const sqlite3_io_methods 
-+  *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl;
- 
-+#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
- 
--/* Takes a fully configured proxy locking-style unix file and switches
--** the local lock file path 
-+#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.
- */
--static int switchLockProxyPath(unixFile *pFile, const char *path) {
--  proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext;
--  char *oldPath = pCtx->lockProxyPath;
--  int rc = SQLITE_OK;
-+static const sqlite3_io_methods *autolockIoFinderImpl(
-+  const char *filePath,    /* name of the database file */
-+  unixFile *pNew           /* the open file object */
-+){
-+  struct flock lockInfo;
- 
--  if( pFile->eFileLock!=NO_LOCK ){
--    return SQLITE_BUSY;
--  }  
-+  if( !filePath ){
-+    /* If filePath==NULL that means we are dealing with a transient file
-+    ** that does not need to be locked. */
-+    return &nolockIoMethods;
-+  }
- 
--  /* nothing to do if the path is NULL, :auto: or matches the existing path */
--  if( !path || path[0]=='\0' || !strcmp(path, ":auto:") ||
--    (oldPath && !strncmp(oldPath, path, MAXPATHLEN)) ){
--    return SQLITE_OK;
-+  /* Test if fcntl() is supported and use POSIX style locks.
-+  ** Otherwise fall back to the named semaphore method.
-+  */
-+  lockInfo.l_len = 1;
-+  lockInfo.l_start = 0;
-+  lockInfo.l_whence = SEEK_SET;
-+  lockInfo.l_type = F_RDLCK;
-+  if( osFcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) {
-+    return &posixIoMethods;
-   }else{
--    unixFile *lockProxy = pCtx->lockProxy;
--    pCtx->lockProxy=NULL;
--    pCtx->conchHeld = 0;
--    if( lockProxy!=NULL ){
--      rc=lockProxy->pMethod->xClose((sqlite3_file *)lockProxy);
--      if( rc ) return rc;
--      sqlite3_free(lockProxy);
--    }
--    sqlite3_free(oldPath);
--    pCtx->lockProxyPath = sqlite3DbStrDup(0, path);
-+    return &semIoMethods;
-   }
--  
--  return rc;
- }
-+static const sqlite3_io_methods 
-+  *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl;
-+
-+#endif /* OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE */
- 
- /*
--** pFile is a file that has been opened by a prior xOpen call.  dbPath
--** is a string buffer at least MAXPATHLEN+1 characters in size.
-+** An abstract type for a pointer to a IO method finder function:
-+*/
-+typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*);
-+
-+
-+/****************************************************************************
-+**************************** sqlite3_vfs methods ****************************
- **
--** This routine find the filename associated with pFile and writes it
--** int dbPath.
-+** This division contains the implementation of methods on the
-+** sqlite3_vfs object.
- */
--static int proxyGetDbPathForUnixFile(unixFile *pFile, char *dbPath){
--#if defined(__APPLE__)
--  if( pFile->pMethod == &afpIoMethods ){
--    /* 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);
--  } else
--#endif
--  if( pFile->pMethod == &dotlockIoMethods ){
--    /* dot lock style uses the locking context to store the dot lock
--    ** file path */
--    int len = strlen((char *)pFile->lockingContext) - strlen(DOTLOCK_SUFFIX);
--    memcpy(dbPath, (char *)pFile->lockingContext, len + 1);
--  }else{
--    /* all other styles use the locking context to store the db file path */
--    assert( strlen((char*)pFile->lockingContext)<=MAXPATHLEN );
--    strlcpy(dbPath, (char *)pFile->lockingContext, MAXPATHLEN);
--  }
--  return SQLITE_OK;
--}
- 
- /*
--** Takes an already filled in unix file and alters it so all file locking 
--** will be performed on the local proxy lock file.  The following fields
--** are preserved in the locking context so that they can be restored and 
--** the unix structure properly cleaned up at close time:
--**  ->lockingContext
--**  ->pMethod
-+** Initialize the contents of the unixFile structure pointed to by pId.
- */
--static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
--  proxyLockingContext *pCtx;
--  char dbPath[MAXPATHLEN+1];       /* Name of the database file */
--  char *lockPath=NULL;
-+static int fillInUnixFile(
-+  sqlite3_vfs *pVfs,      /* Pointer to vfs object */
-+  int h,                  /* Open file descriptor of file being opened */
-+  sqlite3_file *pId,      /* Write to the unixFile structure here */
-+  const char *zFilename,  /* Name of the file being opened */
-+  int ctrlFlags           /* Zero or more UNIXFILE_* values */
-+){
-+  const sqlite3_io_methods *pLockingStyle;
-+  unixFile *pNew = (unixFile *)pId;
-   int rc = SQLITE_OK;
--  
--  if( pFile->eFileLock!=NO_LOCK ){
--    return SQLITE_BUSY;
-+
-+  assert( pNew->pInode==NULL );
-+
-+  /* Usually the path zFilename should not be a relative pathname. The
-+  ** exception is when opening the proxy "conch" file in builds that
-+  ** include the special Apple locking styles.
-+  */
-+#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
-+  assert( zFilename==0 || zFilename[0]=='/' 
-+    || pVfs->pAppData==(void*)&autolockIoFinder );
-+#else
-+  assert( zFilename==0 || zFilename[0]=='/' );
-+#endif
-+
-+  /* No locking occurs in temporary files */
-+  assert( zFilename!=0 || (ctrlFlags & UNIXFILE_NOLOCK)!=0 );
-+
-+  OSTRACE(("OPEN    %-3d %s\n", h, zFilename));
-+  pNew->h = h;
-+  pNew->pVfs = pVfs;
-+  pNew->zPath = zFilename;
-+  pNew->ctrlFlags = (u8)ctrlFlags;
-+  pNew->mmapSizeMax = sqlite3GlobalConfig.szMmap;
-+  if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0),
-+                           "psow", SQLITE_POWERSAFE_OVERWRITE) ){
-+    pNew->ctrlFlags |= UNIXFILE_PSOW;
-   }
--  proxyGetDbPathForUnixFile(pFile, dbPath);
--  if( !path || path[0]=='\0' || !strcmp(path, ":auto:") ){
--    lockPath=NULL;
--  }else{
--    lockPath=(char *)path;
-+  if( strcmp(pVfs->zName,"unix-excl")==0 ){
-+    pNew->ctrlFlags |= UNIXFILE_EXCL;
-   }
--  
--  OSTRACE(("TRANSPROXY  %d for %s pid=%d\n", pFile->h,
--           (lockPath ? lockPath : ":auto:"), getpid()));
- 
--  pCtx = sqlite3_malloc( sizeof(*pCtx) );
--  if( pCtx==0 ){
--    return SQLITE_NOMEM;
-+#if OS_VXWORKS
-+  pNew->pId = vxworksFindFileId(zFilename);
-+  if( pNew->pId==0 ){
-+    ctrlFlags |= UNIXFILE_NOLOCK;
-+    rc = SQLITE_NOMEM;
-   }
--  memset(pCtx, 0, sizeof(*pCtx));
-+#endif
- 
--  rc = proxyCreateConchPathname(dbPath, &pCtx->conchFilePath);
--  if( rc==SQLITE_OK ){
--    rc = proxyCreateUnixFile(pCtx->conchFilePath, &pCtx->conchFile, 0);
--    if( rc==SQLITE_CANTOPEN && ((pFile->openFlags&O_RDWR) == 0) ){
--      /* if (a) the open flags are not O_RDWR, (b) the conch isn't there, and
--      ** (c) the file system is read-only, then enable no-locking access.
--      ** Ugh, since O_RDONLY==0x0000 we test for !O_RDWR since unixOpen asserts
--      ** that openFlags will have only one of O_RDONLY or O_RDWR.
-+  if( ctrlFlags & UNIXFILE_NOLOCK ){
-+    pLockingStyle = &nolockIoMethods;
-+  }else{
-+    pLockingStyle = (**(finder_type*)pVfs->pAppData)(zFilename, pNew);
-+#if SQLITE_ENABLE_LOCKING_STYLE
-+    /* Cache zFilename in the locking context (AFP and dotlock override) for
-+    ** proxyLock activation is possible (remote proxy is based on db name)
-+    ** zFilename remains valid until file is closed, to support */
-+    pNew->lockingContext = (void*)zFilename;
-+#endif
-+  }
-+
-+  if( pLockingStyle == &posixIoMethods
-+#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
-+    || pLockingStyle == &nfsIoMethods
-+#endif
-+  ){
-+    unixEnterMutex();
-+    rc = findInodeInfo(pNew, &pNew->pInode);
-+    if( rc!=SQLITE_OK ){
-+      /* If an error occurred in findInodeInfo(), close the file descriptor
-+      ** immediately, before releasing the mutex. findInodeInfo() may fail
-+      ** in two scenarios:
-+      **
-+      **   (a) A call to fstat() failed.
-+      **   (b) A malloc failed.
-+      **
-+      ** Scenario (b) may only occur if the process is holding no other
-+      ** file descriptors open on the same file. If there were other file
-+      ** descriptors on this file, then no malloc would be required by
-+      ** findInodeInfo(). If this is the case, it is quite safe to close
-+      ** handle h - as it is guaranteed that no posix locks will be released
-+      ** by doing so.
-+      **
-+      ** If scenario (a) caused the error then things are not so safe. The
-+      ** implicit assumption here is that if fstat() fails, things are in
-+      ** such bad shape that dropping a lock or two doesn't matter much.
-       */
--      struct statfs fsInfo;
--      struct stat conchInfo;
--      int goLockless = 0;
-+      robust_close(pNew, h, __LINE__);
-+      h = -1;
-+    }
-+    unixLeaveMutex();
-+  }
- 
--      if( osStat(pCtx->conchFilePath, &conchInfo) == -1 ) {
--        int err = errno;
--        if( (err==ENOENT) && (statfs(dbPath, &fsInfo) != -1) ){
--          goLockless = (fsInfo.f_flags&MNT_RDONLY) == MNT_RDONLY;
--        }
--      }
--      if( goLockless ){
--        pCtx->conchHeld = -1; /* read only FS/ lockless */
--        rc = SQLITE_OK;
-+#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
-+  else if( pLockingStyle == &afpIoMethods ){
-+    /* AFP locking uses the file path so it needs to be included in
-+    ** the afpLockingContext.
-+    */
-+    afpLockingContext *pCtx;
-+    pNew->lockingContext = pCtx = sqlite3_malloc( sizeof(*pCtx) );
-+    if( pCtx==0 ){
-+      rc = SQLITE_NOMEM;
-+    }else{
-+      /* NB: zFilename exists and remains valid until the file is closed
-+      ** according to requirement F11141.  So we do not need to make a
-+      ** copy of the filename. */
-+      pCtx->dbPath = zFilename;
-+      pCtx->reserved = 0;
-+      srandomdev();
-+      unixEnterMutex();
-+      rc = findInodeInfo(pNew, &pNew->pInode);
-+      if( rc!=SQLITE_OK ){
-+        sqlite3_free(pNew->lockingContext);
-+        robust_close(pNew, h, __LINE__);
-+        h = -1;
-       }
-+      unixLeaveMutex();        
-     }
--  }  
--  if( rc==SQLITE_OK && lockPath ){
--    pCtx->lockProxyPath = sqlite3DbStrDup(0, lockPath);
-   }
-+#endif
- 
--  if( rc==SQLITE_OK ){
--    pCtx->dbPath = sqlite3DbStrDup(0, dbPath);
--    if( pCtx->dbPath==NULL ){
-+  else if( pLockingStyle == &dotlockIoMethods ){
-+    /* Dotfile locking uses the file path so it needs to be included in
-+    ** the dotlockLockingContext 
-+    */
-+    char *zLockFile;
-+    int nFilename;
-+    assert( zFilename!=0 );
-+    nFilename = (int)strlen(zFilename) + 6;
-+    zLockFile = (char *)sqlite3_malloc(nFilename);
-+    if( zLockFile==0 ){
-       rc = SQLITE_NOMEM;
-+    }else{
-+      sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename);
-     }
-+    pNew->lockingContext = zLockFile;
-   }
--  if( rc==SQLITE_OK ){
--    /* all memory is allocated, proxys are created and assigned, 
--    ** switch the locking context and pMethod then return.
-+
-+#if OS_VXWORKS
-+  else if( pLockingStyle == &semIoMethods ){
-+    /* Named semaphore locking uses the file path so it needs to be
-+    ** included in the semLockingContext
-     */
--    pCtx->oldLockingContext = pFile->lockingContext;
--    pFile->lockingContext = pCtx;
--    pCtx->pOldMethod = pFile->pMethod;
--    pFile->pMethod = &proxyIoMethods;
--  }else{
--    if( pCtx->conchFile ){ 
--      pCtx->conchFile->pMethod->xClose((sqlite3_file *)pCtx->conchFile);
--      sqlite3_free(pCtx->conchFile);
-+    unixEnterMutex();
-+    rc = findInodeInfo(pNew, &pNew->pInode);
-+    if( (rc==SQLITE_OK) && (pNew->pInode->pSem==NULL) ){
-+      char *zSemName = pNew->pInode->aSemName;
-+      int n;
-+      sqlite3_snprintf(MAX_PATHNAME, zSemName, "/%s.sem",
-+                       pNew->pId->zCanonicalName);
-+      for( n=1; zSemName[n]; n++ )
-+        if( zSemName[n]=='/' ) zSemName[n] = '_';
-+      pNew->pInode->pSem = sem_open(zSemName, O_CREAT, 0666, 1);
-+      if( pNew->pInode->pSem == SEM_FAILED ){
-+        rc = SQLITE_NOMEM;
-+        pNew->pInode->aSemName[0] = '\0';
-+      }
-     }
--    sqlite3DbFree(0, pCtx->lockProxyPath);
--    sqlite3_free(pCtx->conchFilePath); 
--    sqlite3_free(pCtx);
-+    unixLeaveMutex();
-+  }
-+#endif
-+  
-+  pNew->lastErrno = 0;
-+#if OS_VXWORKS
-+  if( rc!=SQLITE_OK ){
-+    if( h>=0 ) robust_close(pNew, h, __LINE__);
-+    h = -1;
-+    osUnlink(zFilename);
-+    pNew->ctrlFlags |= UNIXFILE_DELETE;
-+  }
-+#endif
-+  if( rc!=SQLITE_OK ){
-+    if( h>=0 ) robust_close(pNew, h, __LINE__);
-+  }else{
-+    pNew->pMethod = pLockingStyle;
-+    OpenCounter(+1);
-+    verifyDbFile(pNew);
-   }
--  OSTRACE(("TRANSPROXY  %d %s\n", pFile->h,
--           (rc==SQLITE_OK ? "ok" : "failed")));
-   return rc;
- }
- 
-+/*
-+** Return the name of a directory in which to put temporary files.
-+** If no suitable temporary file directory can be found, return NULL.
-+*/
-+static const char *unixTempFileDir(void){
-+  static const char *azDirs[] = {
-+     0,
-+     0,
-+     "/var/tmp",
-+     "/usr/tmp",
-+     "/tmp",
-+     0        /* List terminator */
-+  };
-+  unsigned int i;
-+  struct stat buf;
-+  const char *zDir = 0;
-+
-+  azDirs[0] = sqlite3_temp_directory;
-+  if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
-+  for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
-+    if( zDir==0 ) continue;
-+    if( osStat(zDir, &buf) ) continue;
-+    if( !S_ISDIR(buf.st_mode) ) continue;
-+    if( osAccess(zDir, 07) ) continue;
-+    break;
-+  }
-+  return zDir;
-+}
- 
- /*
--** This routine handles sqlite3_file_control() calls that are specific
--** to proxy locking.
-+** Create a temporary file name in zBuf.  zBuf must be allocated
-+** by the calling process and must be big enough to hold at least
-+** pVfs->mxPathname bytes.
- */
--static int proxyFileControl(sqlite3_file *id, int op, void *pArg){
--  switch( op ){
--    case SQLITE_GET_LOCKPROXYFILE: {
--      unixFile *pFile = (unixFile*)id;
--      if( pFile->pMethod == &proxyIoMethods ){
--        proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext;
--        proxyTakeConch(pFile);
--        if( pCtx->lockProxyPath ){
--          *(const char **)pArg = pCtx->lockProxyPath;
--        }else{
--          *(const char **)pArg = ":auto: (not held)";
--        }
--      } else {
--        *(const char **)pArg = NULL;
--      }
--      return SQLITE_OK;
-+static int unixGetTempname(int nBuf, char *zBuf){
-+  static const unsigned char zChars[] =
-+    "abcdefghijklmnopqrstuvwxyz"
-+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-+    "0123456789";
-+  unsigned int i, j;
-+  const char *zDir;
-+
-+  /* 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 );
-+
-+  zDir = unixTempFileDir();
-+  if( zDir==0 ) zDir = ".";
-+
-+  /* Check that the output buffer is large enough for the temporary file 
-+  ** name. If it is not, return SQLITE_ERROR.
-+  */
-+  if( (strlen(zDir) + strlen(SQLITE_TEMP_FILE_PREFIX) + 18) >= (size_t)nBuf ){
-+    return SQLITE_ERROR;
-+  }
-+
-+  do{
-+    sqlite3_snprintf(nBuf-18, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir);
-+    j = (int)strlen(zBuf);
-+    sqlite3_randomness(15, &zBuf[j]);
-+    for(i=0; i<15; i++, j++){
-+      zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
-     }
--    case SQLITE_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 */
--          rc = SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/;
--        }else{
--          /* turn off proxy locking - already off - NOOP */
--          rc = SQLITE_OK;
--        }
--      }else{
--        const char *proxyPath = (const char *)pArg;
--        if( isProxyStyle ){
--          proxyLockingContext *pCtx = 
--            (proxyLockingContext*)pFile->lockingContext;
--          if( !strcmp(pArg, ":auto:") 
--           || (pCtx->lockProxyPath &&
--               !strncmp(pCtx->lockProxyPath, proxyPath, MAXPATHLEN))
--          ){
--            rc = SQLITE_OK;
--          }else{
--            rc = switchLockProxyPath(pFile, proxyPath);
--          }
--        }else{
--          /* turn on proxy file locking */
--          rc = proxyTransformUnixFile(pFile, proxyPath);
--        }
--      }
--      return rc;
-+    zBuf[j] = 0;
-+    zBuf[j+1] = 0;
-+  }while( osAccess(zBuf,0)==0 );
-+  return SQLITE_OK;
-+}
-+
-+#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
-+/*
-+** Routine to transform a unixFile into a proxy-locking unixFile.
-+** Implementation in the proxy-lock division, but used by unixOpen()
-+** if SQLITE_PREFER_PROXY_LOCKING is defined.
-+*/
-+static int proxyTransformUnixFile(unixFile*, const char*);
-+#endif
-+
-+/*
-+** Search for an unused file descriptor that was opened on the database 
-+** file (not a journal or master-journal file) identified by pathname
-+** zPath with SQLITE_OPEN_XXX flags matching those passed as the second
-+** argument to this function.
-+**
-+** Such a file descriptor may exist if a database connection was closed
-+** but the associated file descriptor could not be closed because some
-+** other file descriptor open on the same file is holding a file-lock.
-+** Refer to comments in the unixClose() function and the lengthy comment
-+** describing "Posix Advisory Locking" at the start of this file for 
-+** further details. Also, ticket #4018.
-+**
-+** If a suitable file descriptor is found, then it is returned. If no
-+** such file descriptor is located, -1 is returned.
-+*/
-+static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
-+  UnixUnusedFd *pUnused = 0;
-+
-+  /* Do not search for an unused file descriptor on vxworks. Not because
-+  ** vxworks would not benefit from the change (it might, we're not sure),
-+  ** but because no way to test it is currently available. It is better 
-+  ** not to risk breaking vxworks support for the sake of such an obscure 
-+  ** feature.  */
-+#if !OS_VXWORKS
-+  struct stat sStat;                   /* Results of stat() call */
-+
-+  /* A stat() call may fail for various reasons. If this happens, it is
-+  ** almost certain that an open() call on the same path will also fail.
-+  ** For this reason, if an error occurs in the stat() call here, it is
-+  ** ignored and -1 is returned. The caller will try to open a new file
-+  ** 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.  */
-+  if( 0==osStat(zPath, &sStat) ){
-+    unixInodeInfo *pInode;
-+
-+    unixEnterMutex();
-+    pInode = inodeList;
-+    while( pInode && (pInode->fileId.dev!=sStat.st_dev
-+                     || pInode->fileId.ino!=sStat.st_ino) ){
-+       pInode = pInode->pNext;
-     }
--    default: {
--      assert( 0 );  /* The call assures that only valid opcodes are sent */
-+    if( pInode ){
-+      UnixUnusedFd **pp;
-+      for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext));
-+      pUnused = *pp;
-+      if( pUnused ){
-+        *pp = pUnused->pNext;
-+      }
-     }
-+    unixLeaveMutex();
-   }
--  /*NOTREACHED*/
--  return SQLITE_ERROR;
-+#endif    /* if !OS_VXWORKS */
-+  return pUnused;
- }
- 
- /*
--** Within this division (the proxying locking implementation) the procedures
--** above this point are all utilities.  The lock-related methods of the
--** proxy-locking sqlite3_io_method object follow.
-+** This function is called by unixOpen() to determine the unix permissions
-+** to create new files with. If no error occurs, then SQLITE_OK is returned
-+** and a value suitable for passing as the third argument to open(2) is
-+** 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
-+** 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 
-+** this function queries the file-system for the permissions on the 
-+** corresponding database file and sets *pMode to this value. Whenever 
-+** possible, WAL and journal files are created using the same permissions 
-+** as the associated database file.
-+**
-+** If the SQLITE_ENABLE_8_3_NAMES option is enabled, then the
-+** original filename is unavailable.  But 8_3_NAMES is only used for
-+** FAT filesystems and permissions do not matter there, so just use
-+** the default permissions.
- */
-+static int findCreateFileMode(
-+  const char *zPath,              /* Path of file (possibly) being created */
-+  int flags,                      /* Flags passed as 4th argument to xOpen() */
-+  mode_t *pMode,                  /* OUT: Permissions to open file with */
-+  uid_t *pUid,                    /* OUT: uid to set on the file */
-+  gid_t *pGid                     /* OUT: gid to set on the file */
-+){
-+  int rc = SQLITE_OK;             /* Return Code */
-+  *pMode = 0;
-+  *pUid = 0;
-+  *pGid = 0;
-+  if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
-+    char zDb[MAX_PATHNAME+1];     /* Database file path */
-+    int nDb;                      /* Number of valid bytes in zDb */
-+    struct stat sStat;            /* Output of stat() on database file */
- 
-+    /* zPath is a path to a WAL or journal file. The following block derives
-+    ** the path to the associated database file from zPath. This block handles
-+    ** the following naming conventions:
-+    **
-+    **   "<path to db>-journal"
-+    **   "<path to db>-wal"
-+    **   "<path to db>-journalNN"
-+    **   "<path to db>-walNN"
-+    **
-+    ** where NN is a decimal number. The NN naming schemes are 
-+    ** used by the test_multiplex.c module.
-+    */
-+    nDb = sqlite3Strlen30(zPath) - 1; 
-+#ifdef SQLITE_ENABLE_8_3_NAMES
-+    while( nDb>0 && sqlite3Isalnum(zPath[nDb]) ) nDb--;
-+    if( nDb==0 || zPath[nDb]!='-' ) return SQLITE_OK;
-+#else
-+    while( zPath[nDb]!='-' ){
-+      assert( nDb>0 );
-+      assert( zPath[nDb]!='\n' );
-+      nDb--;
-+    }
-+#endif
-+    memcpy(zDb, zPath, nDb);
-+    zDb[nDb] = '\0';
- 
--/*
--** 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, set *pResOut
--** 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 proxyCheckReservedLock(sqlite3_file *id, int *pResOut) {
--  unixFile *pFile = (unixFile*)id;
--  int rc = proxyTakeConch(pFile);
--  if( rc==SQLITE_OK ){
--    proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
--    if( pCtx->conchHeld>0 ){
--      unixFile *proxy = pCtx->lockProxy;
--      return proxy->pMethod->xCheckReservedLock((sqlite3_file*)proxy, pResOut);
--    }else{ /* conchHeld < 0 is lockless */
--      pResOut=0;
-+    if( 0==osStat(zDb, &sStat) ){
-+      *pMode = sStat.st_mode & 0777;
-+      *pUid = sStat.st_uid;
-+      *pGid = sStat.st_gid;
-+    }else{
-+      rc = SQLITE_IOERR_FSTAT;
-     }
-+  }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){
-+    *pMode = 0600;
-   }
-   return rc;
- }
- 
- /*
--** Lock the file with the lock specified by parameter eFileLock - one
--** of the following:
-+** Open the file zPath.
-+** 
-+** Previously, the SQLite OS layer used three functions in place of this
-+** one:
- **
--**     (1) SHARED_LOCK
--**     (2) RESERVED_LOCK
--**     (3) PENDING_LOCK
--**     (4) EXCLUSIVE_LOCK
-+**     sqlite3OsOpenReadWrite();
-+**     sqlite3OsOpenReadOnly();
-+**     sqlite3OsOpenExclusive();
- **
--** 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:
-+** These calls correspond to the following combinations of flags:
- **
--**    UNLOCKED -> SHARED
--**    SHARED -> RESERVED
--**    SHARED -> (PENDING) -> EXCLUSIVE
--**    RESERVED -> (PENDING) -> EXCLUSIVE
--**    PENDING -> EXCLUSIVE
-+**     ReadWrite() ->     (READWRITE | CREATE)
-+**     ReadOnly()  ->     (READONLY) 
-+**     OpenExclusive() -> (READWRITE | CREATE | EXCLUSIVE)
- **
--** This routine will only increase a lock.  Use the sqlite3OsUnlock()
--** routine to lower a locking level.
-+** The old OpenExclusive() accepted a boolean argument - "delFlag". If
-+** true, the file was configured to be automatically deleted when the
-+** file handle closed. To achieve the same effect using this new 
-+** interface, add the DELETEONCLOSE flag to those specified above for 
-+** OpenExclusive().
- */
--static int proxyLock(sqlite3_file *id, int eFileLock) {
--  unixFile *pFile = (unixFile*)id;
--  int rc = proxyTakeConch(pFile);
--  if( rc==SQLITE_OK ){
--    proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
--    if( pCtx->conchHeld>0 ){
--      unixFile *proxy = pCtx->lockProxy;
--      rc = proxy->pMethod->xLock((sqlite3_file*)proxy, eFileLock);
--      pFile->eFileLock = proxy->eFileLock;
--    }else{
--      /* conchHeld < 0 is lockless */
--    }
--  }
--  return rc;
--}
-+static int unixOpen(
-+  sqlite3_vfs *pVfs,           /* The VFS for which this is the xOpen method */
-+  const char *zPath,           /* Pathname of file to be opened */
-+  sqlite3_file *pFile,         /* The file descriptor to be filled in */
-+  int flags,                   /* Input flags to control the opening */
-+  int *pOutFlags               /* Output flags returned to SQLite core */
-+){
-+  unixFile *p = (unixFile *)pFile;
-+  int fd = -1;                   /* File descriptor returned by open() */
-+  int openFlags = 0;             /* Flags to pass to open() */
-+  int eType = flags&0xFFFFFF00;  /* Type of file to open */
-+  int noLock;                    /* True to omit locking primitives */
-+  int rc = SQLITE_OK;            /* Function Return Code */
-+  int ctrlFlags = 0;             /* UNIXFILE_* flags */
- 
-+  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 SQLITE_ENABLE_LOCKING_STYLE
-+  int isAutoProxy  = (flags & SQLITE_OPEN_AUTOPROXY);
-+#endif
-+#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
-+  struct statfs fsInfo;
-+#endif
- 
--/*
--** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
--** 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.
--*/
--static int proxyUnlock(sqlite3_file *id, int eFileLock) {
--  unixFile *pFile = (unixFile*)id;
--  int rc = proxyTakeConch(pFile);
--  if( rc==SQLITE_OK ){
--    proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
--    if( pCtx->conchHeld>0 ){
--      unixFile *proxy = pCtx->lockProxy;
--      rc = proxy->pMethod->xUnlock((sqlite3_file*)proxy, eFileLock);
--      pFile->eFileLock = proxy->eFileLock;
-+  /* If creating a master or main-file journal, this function will open
-+  ** a file-descriptor on the directory too. The first time unixSync()
-+  ** is called the directory file descriptor will be fsync()ed and close()d.
-+  */
-+  int syncDir = (isCreate && (
-+        eType==SQLITE_OPEN_MASTER_JOURNAL 
-+     || eType==SQLITE_OPEN_MAIN_JOURNAL 
-+     || eType==SQLITE_OPEN_WAL
-+  ));
-+
-+  /* 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[MAX_PATHNAME+2];
-+  const char *zName = zPath;
-+
-+  /* 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
-+  );
-+
-+  memset(p, 0, sizeof(unixFile));
-+
-+  if( eType==SQLITE_OPEN_MAIN_DB ){
-+    UnixUnusedFd *pUnused;
-+    pUnused = findReusableFd(zName, flags);
-+    if( pUnused ){
-+      fd = pUnused->fd;
-     }else{
--      /* conchHeld < 0 is lockless */
-+      pUnused = sqlite3_malloc(sizeof(*pUnused));
-+      if( !pUnused ){
-+        return SQLITE_NOMEM;
-+      }
-     }
--  }
--  return rc;
--}
-+    p->pUnused = pUnused;
- 
--/*
--** Close a file that uses proxy locks.
--*/
--static int proxyClose(sqlite3_file *id) {
--  if( id ){
--    unixFile *pFile = (unixFile*)id;
--    proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
--    unixFile *lockProxy = pCtx->lockProxy;
--    unixFile *conchFile = pCtx->conchFile;
--    int rc = SQLITE_OK;
--    
--    if( lockProxy ){
--      rc = lockProxy->pMethod->xUnlock((sqlite3_file*)lockProxy, NO_LOCK);
--      if( rc ) return rc;
--      rc = lockProxy->pMethod->xClose((sqlite3_file*)lockProxy);
--      if( rc ) return rc;
--      sqlite3_free(lockProxy);
--      pCtx->lockProxy = 0;
--    }
--    if( conchFile ){
--      if( pCtx->conchHeld ){
--        rc = proxyReleaseConch(pFile);
--        if( rc ) return rc;
--      }
--      rc = conchFile->pMethod->xClose((sqlite3_file*)conchFile);
--      if( rc ) return rc;
--      sqlite3_free(conchFile);
-+    /* Database filenames are double-zero terminated if they are not
-+    ** URIs with parameters.  Hence, they can always be passed into
-+    ** sqlite3_uri_parameter(). */
-+    assert( (flags & SQLITE_OPEN_URI) || zName[strlen(zName)+1]==0 );
-+
-+  }else if( !zName ){
-+    /* If zName is NULL, the upper layer is requesting a temp file. */
-+    assert(isDelete && !syncDir);
-+    rc = unixGetTempname(MAX_PATHNAME+2, zTmpname);
-+    if( rc!=SQLITE_OK ){
-+      return rc;
-     }
--    sqlite3DbFree(0, pCtx->lockProxyPath);
--    sqlite3_free(pCtx->conchFilePath);
--    sqlite3DbFree(0, pCtx->dbPath);
--    /* restore the original locking context and pMethod then close it */
--    pFile->lockingContext = pCtx->oldLockingContext;
--    pFile->pMethod = pCtx->pOldMethod;
--    sqlite3_free(pCtx);
--    return pFile->pMethod->xClose(id);
-+    zName = zTmpname;
-+
-+    /* Generated temporary filenames are always double-zero terminated
-+    ** for use by sqlite3_uri_parameter(). */
-+    assert( zName[strlen(zName)+1]==0 );
-   }
--  return SQLITE_OK;
--}
- 
-+  /* Determine the value of the flags parameter passed to POSIX function
-+  ** open(). These must be calculated even if open() is not called, as
-+  ** they may be stored as part of the file handle and used by the 
-+  ** 'conch file' locking functions later on.  */
-+  if( isReadonly )  openFlags |= O_RDONLY;
-+  if( isReadWrite ) openFlags |= O_RDWR;
-+  if( isCreate )    openFlags |= O_CREAT;
-+  if( isExclusive ) openFlags |= (O_EXCL|O_NOFOLLOW);
-+  openFlags |= (O_LARGEFILE|O_BINARY);
- 
-+  if( fd<0 ){
-+    mode_t openMode;              /* Permissions to create file with */
-+    uid_t uid;                    /* Userid for the file */
-+    gid_t gid;                    /* Groupid for the file */
-+    rc = findCreateFileMode(zName, flags, &openMode, &uid, &gid);
-+    if( rc!=SQLITE_OK ){
-+      assert( !p->pUnused );
-+      assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL );
-+      return rc;
-+    }
-+    fd = robust_open(zName, openFlags, openMode);
-+    OSTRACE(("OPENX   %-3d %s 0%o\n", fd, zName, openFlags));
-+    if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){
-+      /* Failed to open the file for read/write access. Try read-only. */
-+      flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
-+      openFlags &= ~(O_RDWR|O_CREAT);
-+      flags |= SQLITE_OPEN_READONLY;
-+      openFlags |= O_RDONLY;
-+      isReadonly = 1;
-+      fd = robust_open(zName, openFlags, openMode);
-+    }
-+    if( fd<0 ){
-+      rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
-+      goto open_finished;
-+    }
- 
--#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
--/*
--** The proxy locking style is intended for use with AFP filesystems.
--** And since AFP is only supported on MacOSX, the proxy locking is also
--** restricted to MacOSX.
--** 
--**
--******************* End of the proxy lock implementation **********************
--******************************************************************************/
-+    /* If this process is running as root and if creating a new rollback
-+    ** journal or WAL file, set the ownership of the journal or WAL to be
-+    ** the same as the original database.
-+    */
-+    if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
-+      osFchown(fd, uid, gid);
-+    }
-+  }
-+  assert( fd>=0 );
-+  if( pOutFlags ){
-+    *pOutFlags = flags;
-+  }
- 
--/*
--** Initialize the operating system interface.
--**
--** This routine registers all VFS implementations for unix-like operating
--** systems.  This routine, and the sqlite3_os_end() routine that follows,
--** should be the only routines in this file that are visible from other
--** files.
--**
--** This routine is called once during SQLite initialization and by a
--** single thread.  The memory allocation and mutex subsystems have not
--** necessarily been initialized when this routine is called, and so they
--** should not be used.
--*/
--SQLITE_API int 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
--  ** to the "finder" function.  (pAppData is a pointer to a pointer because
--  ** silly C90 rules prohibit a void* from being cast to a function pointer
--  ** and so we have to go through the intermediate pointer to avoid problems
--  ** when compiling with -pedantic-errors on GCC.)
--  **
--  ** The FINDER parameter to this macro is the name of the pointer to the
--  ** finder-function.  The finder-function returns a pointer to the
--  ** sqlite_io_methods object that implements the desired locking
--  ** behaviors.  See the division above that contains the IOMETHODS
--  ** macro for addition information on finder-functions.
--  **
--  ** Most finders simply return a pointer to a fixed sqlite3_io_methods
--  ** object.  But the "autolockIoFinder" available on MacOSX does a little
--  ** more than that; it looks at the filesystem type that hosts the 
--  ** database file and tries to choose an locking method appropriate for
--  ** that filesystem time.
--  */
--  #define UNIXVFS(VFSNAME, FINDER) {                        \
--    3,                    /* iVersion */                    \
--    sizeof(unixFile),     /* szOsFile */                    \
--    MAX_PATHNAME,         /* mxPathname */                  \
--    0,                    /* pNext */                       \
--    VFSNAME,              /* zName */                       \
--    (void*)&FINDER,       /* pAppData */                    \
--    unixOpen,             /* xOpen */                       \
--    unixDelete,           /* xDelete */                     \
--    unixAccess,           /* xAccess */                     \
--    unixFullPathname,     /* xFullPathname */               \
--    unixDlOpen,           /* xDlOpen */                     \
--    unixDlError,          /* xDlError */                    \
--    unixDlSym,            /* xDlSym */                      \
--    unixDlClose,          /* xDlClose */                    \
--    unixRandomness,       /* xRandomness */                 \
--    unixSleep,            /* xSleep */                      \
--    unixCurrentTime,      /* xCurrentTime */                \
--    unixGetLastError,     /* xGetLastError */               \
--    unixCurrentTimeInt64, /* xCurrentTimeInt64 */           \
--    unixSetSystemCall,    /* xSetSystemCall */              \
--    unixGetSystemCall,    /* xGetSystemCall */              \
--    unixNextSystemCall,   /* xNextSystemCall */             \
-+  if( p->pUnused ){
-+    p->pUnused->fd = fd;
-+    p->pUnused->flags = flags;
-   }
- 
--  /*
--  ** All default VFSes for unix are contained in the following array.
--  **
--  ** Note that the sqlite3_vfs.pNext field of the VFS object is modified
--  ** by the SQLite core when the VFS is registered.  So the following
--  ** array cannot be const.
--  */
--  static sqlite3_vfs aVfs[] = {
--#if SQLITE_ENABLE_LOCKING_STYLE && (OS_VXWORKS || defined(__APPLE__))
--    UNIXVFS("unix",          autolockIoFinder ),
--#else
--    UNIXVFS("unix",          posixIoFinder ),
--#endif
--    UNIXVFS("unix-none",     nolockIoFinder ),
--    UNIXVFS("unix-dotfile",  dotlockIoFinder ),
--    UNIXVFS("unix-excl",     posixIoFinder ),
-+  if( isDelete ){
- #if OS_VXWORKS
--    UNIXVFS("unix-namedsem", semIoFinder ),
-+    zPath = zName;
-+#else
-+    osUnlink(zName);
- #endif
-+  }
- #if SQLITE_ENABLE_LOCKING_STYLE
--    UNIXVFS("unix-posix",    posixIoFinder ),
--#if !OS_VXWORKS
--    UNIXVFS("unix-flock",    flockIoFinder ),
-+  else{
-+    p->openFlags = openFlags;
-+  }
-+#endif
-+
-+  noLock = eType!=SQLITE_OPEN_MAIN_DB;
-+
-+  
-+#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
-+  if( fstatfs(fd, &fsInfo) == -1 ){
-+    ((unixFile*)pFile)->lastErrno = 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;
-+  }
- #endif
-+
-+  /* Set up appropriate ctrlFlags */
-+  if( isDelete )                ctrlFlags |= UNIXFILE_DELETE;
-+  if( isReadonly )              ctrlFlags |= UNIXFILE_RDONLY;
-+  if( noLock )                  ctrlFlags |= UNIXFILE_NOLOCK;
-+  if( syncDir )                 ctrlFlags |= UNIXFILE_DIRSYNC;
-+  if( flags & SQLITE_OPEN_URI ) ctrlFlags |= UNIXFILE_URI;
-+
-+#if SQLITE_ENABLE_LOCKING_STYLE
-+#if SQLITE_PREFER_PROXY_LOCKING
-+  isAutoProxy = 1;
- #endif
--#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
--    UNIXVFS("unix-afp",      afpIoFinder ),
--    UNIXVFS("unix-nfs",      nfsIoFinder ),
--    UNIXVFS("unix-proxy",    proxyIoFinder ),
-+  if( isAutoProxy && (zPath!=NULL) && (!noLock) && pVfs->xOpen ){
-+    char *envforce = getenv("SQLITE_FORCE_PROXY_LOCKING");
-+    int useProxy = 0;
-+
-+    /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, 0 means 
-+    ** never use proxy, NULL means use proxy for non-local files only.  */
-+    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 ){
-+      rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags);
-+      if( rc==SQLITE_OK ){
-+        rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:");
-+        if( rc!=SQLITE_OK ){
-+          /* Use unixClose to clean up the resources added in fillInUnixFile 
-+          ** and clear all the structure's references.  Specifically, 
-+          ** pFile->pMethods will be NULL so sqlite3OsClose will be a no-op 
-+          */
-+          unixClose(pFile);
-+          return rc;
-+        }
-+      }
-+      goto open_finished;
-+    }
-+  }
- #endif
--  };
--  unsigned int i;          /* Loop counter */
--
--  /* Double-check that the aSyscall[] array has been constructed
--  ** correctly.  See ticket [bb3a86e890c8e96ab] */
--  assert( ArraySize(aSyscall)==24 );
-+  
-+  rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags);
- 
--  /* Register all VFSes defined in the aVfs[] array */
--  for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
--    sqlite3_vfs_register(&aVfs[i], i==0);
-+open_finished:
-+  if( rc!=SQLITE_OK ){
-+    sqlite3_free(p->pUnused);
-   }
--  return SQLITE_OK; 
--}
--
--/*
--** Shutdown the operating system interface.
--**
--** Some operating systems might need to do some cleanup in this routine,
--** to release dynamically allocated objects.  But not on unix.
--** This routine is a no-op for unix.
--*/
--SQLITE_API int sqlite3_os_end(void){ 
--  return SQLITE_OK; 
-+  return rc;
- }
-- 
--#endif /* SQLITE_OS_UNIX */
- 
--/************** End of os_unix.c *********************************************/
--/************** Begin file os_win.c ******************************************/
--/*
--** 2004 May 22
--**
--** 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 Windows.
--*/
--#if SQLITE_OS_WIN               /* This file is used for Windows only */
--
--#ifdef __CYGWIN__
--# include <sys/cygwin.h>
--#endif
--
--/*
--** Include code that is common to all os_*.c files
--*/
--/************** Include os_common.h in the middle of os_win.c ****************/
--/************** Begin file os_common.h ***************************************/
--/*
--** 2004 May 22
--**
--** 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 macros and a little bit of code that is common to
--** all of the platform-specific files (os_*.c) and is #included into those
--** files.
--**
--** This file should be #included by the os_*.c files only.  It is not a
--** general purpose header file.
--*/
--#ifndef _OS_COMMON_H_
--#define _OS_COMMON_H_
- 
- /*
--** At least two bugs have slipped in because we changed the MEMORY_DEBUG
--** macro to SQLITE_DEBUG and some older makefiles have not yet made the
--** switch.  The following code should catch this problem at compile-time.
-+** Delete the file at zPath. If the dirSync argument is true, fsync()
-+** the directory after deleting the file.
- */
--#ifdef MEMORY_DEBUG
--# 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
-+static int unixDelete(
-+  sqlite3_vfs *NotUsed,     /* VFS containing this as the xDelete method */
-+  const char *zPath,        /* Name of file to be deleted */
-+  int dirSync               /* If true, fsync() directory after deleting file */
-+){
-+  int rc = SQLITE_OK;
-+  UNUSED_PARAMETER(NotUsed);
-+  SimulateIOError(return SQLITE_IOERR_DELETE);
-+  if( osUnlink(zPath)==(-1) ){
-+    if( errno==ENOENT ){
-+      rc = SQLITE_IOERR_DELETE_NOENT;
-+    }else{
-+      rc = unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath);
-+    }
-+    return rc;
-+  }
-+#ifndef SQLITE_DISABLE_DIRSYNC
-+  if( (dirSync & 1)!=0 ){
-+    int fd;
-+    rc = osOpenDirectory(zPath, &fd);
-+    if( rc==SQLITE_OK ){
-+#if OS_VXWORKS
-+      if( fsync(fd)==-1 )
- #else
--# define OSTRACE(X)
-+      if( fsync(fd) )
- #endif
-+      {
-+        rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath);
-+      }
-+      robust_close(0, fd, __LINE__);
-+    }else if( rc==SQLITE_CANTOPEN ){
-+      rc = SQLITE_OK;
-+    }
-+  }
-+#endif
-+  return rc;
-+}
- 
- /*
--** Macros for performance tracing.  Normally turned off.  Only works
--** on i486 hardware.
--*/
--#ifdef SQLITE_PERFORMANCE_TRACE
--
--/* 
--** hwtime.h contains inline assembler code for implementing 
--** high-performance timing routines.
--*/
--/************** Include hwtime.h in the middle of os_common.h ****************/
--/************** Begin file hwtime.h ******************************************/
--/*
--** 2008 May 27
--**
--** 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.
-+** Test the existence of or access permissions of file zPath. The
-+** test performed depends on the value of flags:
- **
--******************************************************************************
-+**     SQLITE_ACCESS_EXISTS: Return 1 if the file exists
-+**     SQLITE_ACCESS_READWRITE: Return 1 if the file is read and writable.
-+**     SQLITE_ACCESS_READONLY: Return 1 if the file is readable.
- **
--** This file contains inline asm code for retrieving "high-performance"
--** counters for x86 class CPUs.
--*/
--#ifndef _HWTIME_H_
--#define _HWTIME_H_
--
--/*
--** The following routine only works on pentium-class (or newer) processors.
--** It uses the RDTSC opcode to read the cycle count value out of the
--** processor and returns that value.  This can be used for high-res
--** profiling.
-+** Otherwise return 0.
- */
--#if (defined(__GNUC__) || defined(_MSC_VER)) && \
--      (defined(i386) || defined(__i386__) || defined(_M_IX86))
--
--  #if defined(__GNUC__)
--
--  __inline__ sqlite_uint64 sqlite3Hwtime(void){
--     unsigned int lo, hi;
--     __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
--     return (sqlite_uint64)hi << 32 | lo;
--  }
--
--  #elif defined(_MSC_VER)
--
--  __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
--     __asm {
--        rdtsc
--        ret       ; return value at EDX:EAX
--     }
--  }
--
--  #endif
--
--#elif (defined(__GNUC__) && defined(__x86_64__))
-+static int unixAccess(
-+  sqlite3_vfs *NotUsed,   /* The VFS containing this xAccess method */
-+  const char *zPath,      /* Path of the file to examine */
-+  int flags,              /* What do we want to learn about the zPath file? */
-+  int *pResOut            /* Write result boolean here */
-+){
-+  int amode = 0;
-+  UNUSED_PARAMETER(NotUsed);
-+  SimulateIOError( return SQLITE_IOERR_ACCESS; );
-+  switch( flags ){
-+    case SQLITE_ACCESS_EXISTS:
-+      amode = F_OK;
-+      break;
-+    case SQLITE_ACCESS_READWRITE:
-+      amode = W_OK|R_OK;
-+      break;
-+    case SQLITE_ACCESS_READ:
-+      amode = R_OK;
-+      break;
- 
--  __inline__ sqlite_uint64 sqlite3Hwtime(void){
--      unsigned long val;
--      __asm__ __volatile__ ("rdtsc" : "=A" (val));
--      return val;
-+    default:
-+      assert(!"Invalid flags argument");
-   }
-- 
--#elif (defined(__GNUC__) && defined(__ppc__))
--
--  __inline__ sqlite_uint64 sqlite3Hwtime(void){
--      unsigned long long retval;
--      unsigned long junk;
--      __asm__ __volatile__ ("\n\
--          1:      mftbu   %1\n\
--                  mftb    %L0\n\
--                  mftbu   %0\n\
--                  cmpw    %0,%1\n\
--                  bne     1b"
--                  : "=r" (retval), "=r" (junk));
--      return retval;
-+  *pResOut = (osAccess(zPath, amode)==0);
-+  if( flags==SQLITE_ACCESS_EXISTS && *pResOut ){
-+    struct stat buf;
-+    if( 0==osStat(zPath, &buf) && buf.st_size==0 ){
-+      *pResOut = 0;
-+    }
-   }
-+  return SQLITE_OK;
-+}
- 
--#else
- 
--  #error Need implementation of sqlite3Hwtime() for your platform.
-+/*
-+** Turn a relative pathname into a full pathname. The relative path
-+** is stored as a nul-terminated string in the buffer pointed to by
-+** zPath. 
-+**
-+** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes 
-+** (in this case, MAX_PATHNAME bytes). The full-path is written to
-+** this buffer before returning.
-+*/
-+static int unixFullPathname(
-+  sqlite3_vfs *pVfs,            /* Pointer to vfs object */
-+  const char *zPath,            /* Possibly relative input path */
-+  int nOut,                     /* Size of output buffer in bytes */
-+  char *zOut                    /* Output buffer */
-+){
- 
--  /*
--  ** To compile without implementing sqlite3Hwtime() for your platform,
--  ** you can remove the above #error and use the following
--  ** stub function.  You will lose timing support for many
--  ** of the debugging and testing utilities, but it should at
--  ** least compile and run.
-+  /* 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.
-   */
--SQLITE_PRIVATE   sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
--
--#endif
-+  SimulateIOError( return SQLITE_ERROR );
- 
--#endif /* !defined(_HWTIME_H_) */
-+  assert( pVfs->mxPathname==MAX_PATHNAME );
-+  UNUSED_PARAMETER(pVfs);
- 
--/************** End of hwtime.h **********************************************/
--/************** Continuing where we left off in os_common.h ******************/
-+  zOut[nOut-1] = '\0';
-+  if( zPath[0]=='/' ){
-+    sqlite3_snprintf(nOut, zOut, "%s", zPath);
-+  }else{
-+    int nCwd;
-+    if( osGetcwd(zOut, nOut-1)==0 ){
-+      return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
-+    }
-+    nCwd = (int)strlen(zOut);
-+    sqlite3_snprintf(nOut-nCwd, &zOut[nCwd], "/%s", zPath);
-+  }
-+  return SQLITE_OK;
-+}
- 
--static sqlite_uint64 g_start;
--static sqlite_uint64 g_elapsed;
--#define TIMER_START       g_start=sqlite3Hwtime()
--#define TIMER_END         g_elapsed=sqlite3Hwtime()-g_start
--#define TIMER_ELAPSED     g_elapsed
--#else
--#define TIMER_START
--#define TIMER_END
--#define TIMER_ELAPSED     ((sqlite_uint64)0)
--#endif
- 
-+#ifndef SQLITE_OMIT_LOAD_EXTENSION
- /*
--** If we compile with the SQLITE_TEST macro set, then the following block
--** of code will give us the ability to simulate a disk I/O error.  This
--** is used for testing the I/O recovery logic.
-+** Interfaces for opening a shared library, finding entry points
-+** within the shared library, and closing the shared library.
- */
--#ifdef SQLITE_TEST
--SQLITE_API int sqlite3_io_error_hit = 0;            /* Total number of I/O Errors */
--SQLITE_API int sqlite3_io_error_hardhit = 0;        /* Number of non-benign errors */
--SQLITE_API int sqlite3_io_error_pending = 0;        /* Count down to first I/O error */
--SQLITE_API int sqlite3_io_error_persist = 0;        /* True if I/O errors persist */
--SQLITE_API int sqlite3_io_error_benign = 0;         /* True if errors are benign */
--SQLITE_API int sqlite3_diskfull_pending = 0;
--SQLITE_API int sqlite3_diskfull = 0;
--#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X)
--#define SimulateIOError(CODE)  \
--  if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \
--       || sqlite3_io_error_pending-- == 1 )  \
--              { local_ioerr(); CODE; }
--static void local_ioerr(){
--  IOTRACE(("IOERR\n"));
--  sqlite3_io_error_hit++;
--  if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++;
-+#include <dlfcn.h>
-+static void *unixDlOpen(sqlite3_vfs *NotUsed, const char *zFilename){
-+  UNUSED_PARAMETER(NotUsed);
-+  return dlopen(zFilename, RTLD_NOW | RTLD_GLOBAL);
- }
--#define SimulateDiskfullError(CODE) \
--   if( sqlite3_diskfull_pending ){ \
--     if( sqlite3_diskfull_pending == 1 ){ \
--       local_ioerr(); \
--       sqlite3_diskfull = 1; \
--       sqlite3_io_error_hit = 1; \
--       CODE; \
--     }else{ \
--       sqlite3_diskfull_pending--; \
--     } \
--   }
--#else
--#define SimulateIOErrorBenign(X)
--#define SimulateIOError(A)
--#define SimulateDiskfullError(A)
--#endif
- 
- /*
--** When testing, keep a count of the number of open files.
-+** SQLite calls this function immediately after a call to unixDlSym() or
-+** unixDlOpen() fails (returns a null pointer). If a more detailed error
-+** message is available, it is written to zBufOut. If no error message
-+** is available, zBufOut is left unmodified and SQLite uses a default
-+** error message.
- */
--#ifdef SQLITE_TEST
--SQLITE_API int sqlite3_open_file_count = 0;
--#define OpenCounter(X)  sqlite3_open_file_count+=(X)
--#else
--#define OpenCounter(X)
-+static void unixDlError(sqlite3_vfs *NotUsed, int nBuf, char *zBufOut){
-+  const char *zErr;
-+  UNUSED_PARAMETER(NotUsed);
-+  unixEnterMutex();
-+  zErr = dlerror();
-+  if( zErr ){
-+    sqlite3_snprintf(nBuf, zBufOut, "%s", zErr);
-+  }
-+  unixLeaveMutex();
-+}
-+static void (*unixDlSym(sqlite3_vfs *NotUsed, void *p, const char*zSym))(void){
-+  /* 
-+  ** GCC with -pedantic-errors says that C90 does not allow a void* to be
-+  ** cast into a pointer to a function.  And yet the library dlsym() routine
-+  ** returns a void* which is really a pointer to a function.  So how do we
-+  ** use dlsym() with -pedantic-errors?
-+  **
-+  ** Variable x below is defined to be a pointer to a function taking
-+  ** parameters void* and const char* and returning a pointer to a function.
-+  ** We initialize x by assigning it a pointer to the dlsym() function.
-+  ** (That assignment requires a cast.)  Then we call the function that
-+  ** x points to.  
-+  **
-+  ** This work-around is unlikely to work correctly on any system where
-+  ** you really cannot cast a function pointer into void*.  But then, on the
-+  ** other hand, dlsym() will not work on such a system either, so we have
-+  ** not really lost anything.
-+  */
-+  void (*(*x)(void*,const char*))(void);
-+  UNUSED_PARAMETER(NotUsed);
-+  x = (void(*(*)(void*,const char*))(void))dlsym;
-+  return (*x)(p, zSym);
-+}
-+static void unixDlClose(sqlite3_vfs *NotUsed, void *pHandle){
-+  UNUSED_PARAMETER(NotUsed);
-+  dlclose(pHandle);
-+}
-+#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
-+  #define unixDlOpen  0
-+  #define unixDlError 0
-+  #define unixDlSym   0
-+  #define unixDlClose 0
- #endif
- 
--#endif /* !defined(_OS_COMMON_H_) */
--
--/************** End of os_common.h *******************************************/
--/************** Continuing where we left off in os_win.c *********************/
--
- /*
--** Compiling and using WAL mode requires several APIs that are only
--** available in Windows platforms based on the NT kernel.
-+** Write nBuf bytes of random data to the supplied buffer zBuf.
- */
--#if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL)
--# error "WAL mode requires support from the Windows NT kernel, compile\
-- with SQLITE_OMIT_WAL."
-+static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){
-+  UNUSED_PARAMETER(NotUsed);
-+  assert((size_t)nBuf>=(sizeof(time_t)+sizeof(int)));
-+
-+  /* We have to initialize zBuf to prevent valgrind from reporting
-+  ** errors.  The reports issued by valgrind are incorrect - we would
-+  ** prefer that the randomness be increased by making use of the
-+  ** uninitialized space in zBuf - but valgrind errors tend to worry
-+  ** some users.  Rather than argue, it seems easier just to initialize
-+  ** the whole array and silence valgrind, even if that means less randomness
-+  ** in the random seed.
-+  **
-+  ** When testing, initializing zBuf[] to zero is all we do.  That means
-+  ** that we always use the same random number sequence.  This makes the
-+  ** tests repeatable.
-+  */
-+  memset(zBuf, 0, nBuf);
-+#if !defined(SQLITE_TEST)
-+  {
-+    int pid, fd, got;
-+    fd = robust_open("/dev/urandom", O_RDONLY, 0);
-+    if( fd<0 ){
-+      time_t t;
-+      time(&t);
-+      memcpy(zBuf, &t, sizeof(t));
-+      pid = getpid();
-+      memcpy(&zBuf[sizeof(t)], &pid, sizeof(pid));
-+      assert( sizeof(t)+sizeof(pid)<=(size_t)nBuf );
-+      nBuf = sizeof(t) + sizeof(pid);
-+    }else{
-+      do{ got = osRead(fd, zBuf, nBuf); }while( got<0 && errno==EINTR );
-+      robust_close(0, fd, __LINE__);
-+    }
-+  }
- #endif
-+  return nBuf;
-+}
-+
- 
- /*
--** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions
--** based on the sub-platform)?
-+** Sleep for a little while.  Return the amount of time slept.
-+** The argument is the number of microseconds we want to sleep.
-+** The return value is the number of microseconds of sleep actually
-+** requested from the underlying operating system, a number which
-+** might be greater than or equal to the argument, but not less
-+** than the argument.
- */
--#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
--#  define SQLITE_WIN32_HAS_ANSI
-+static int unixSleep(sqlite3_vfs *NotUsed, int microseconds){
-+#if OS_VXWORKS
-+  struct timespec sp;
-+
-+  sp.tv_sec = microseconds / 1000000;
-+  sp.tv_nsec = (microseconds % 1000000) * 1000;
-+  nanosleep(&sp, NULL);
-+  UNUSED_PARAMETER(NotUsed);
-+  return microseconds;
-+#elif defined(HAVE_USLEEP) && HAVE_USLEEP
-+  usleep(microseconds);
-+  UNUSED_PARAMETER(NotUsed);
-+  return microseconds;
-+#else
-+  int seconds = (microseconds+999999)/1000000;
-+  sleep(seconds);
-+  UNUSED_PARAMETER(NotUsed);
-+  return seconds*1000000;
- #endif
-+}
- 
- /*
--** Are most of the Win32 Unicode APIs available (i.e. with certain exceptions
--** based on the sub-platform)?
-+** 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.
- */
--#if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT
--#  define SQLITE_WIN32_HAS_WIDE
-+#ifdef SQLITE_TEST
-+SQLITE_API int sqlite3_current_time = 0;  /* Fake system time in seconds since 1970. */
- #endif
- 
- /*
--** 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)?
--*/
--#if SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL)
--/*
--** Two of the file mapping APIs are different under WinRT.  Figure out which
--** set we need.
-+** 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.
- */
--#if SQLITE_OS_WINRT
--WINBASEAPI HANDLE WINAPI CreateFileMappingFromApp(HANDLE, \
--        LPSECURITY_ATTRIBUTES, ULONG, ULONG64, LPCWSTR);
--
--WINBASEAPI LPVOID WINAPI MapViewOfFileFromApp(HANDLE, ULONG, ULONG64, SIZE_T);
-+static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){
-+  static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
-+  int rc = SQLITE_OK;
-+#if defined(NO_GETTOD)
-+  time_t t;
-+  time(&t);
-+  *piNow = ((sqlite3_int64)t)*1000 + unixEpoch;
-+#elif OS_VXWORKS
-+  struct timespec sNow;
-+  clock_gettime(CLOCK_REALTIME, &sNow);
-+  *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_nsec/1000000;
- #else
--#if defined(SQLITE_WIN32_HAS_ANSI)
--WINBASEAPI HANDLE WINAPI CreateFileMappingA(HANDLE, LPSECURITY_ATTRIBUTES, \
--        DWORD, DWORD, DWORD, LPCSTR);
--#endif /* defined(SQLITE_WIN32_HAS_ANSI) */
--
--#if defined(SQLITE_WIN32_HAS_WIDE)
--WINBASEAPI HANDLE WINAPI CreateFileMappingW(HANDLE, LPSECURITY_ATTRIBUTES, \
--        DWORD, DWORD, DWORD, LPCWSTR);
--#endif /* defined(SQLITE_WIN32_HAS_WIDE) */
--
--WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T);
--#endif /* SQLITE_OS_WINRT */
-+  struct timeval sNow;
-+  if( gettimeofday(&sNow, 0)==0 ){
-+    *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000;
-+  }else{
-+    rc = SQLITE_ERROR;
-+  }
-+#endif
- 
--/*
--** This file mapping API is common to both Win32 and WinRT.
--*/
--WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID);
--#endif /* SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL) */
-+#ifdef SQLITE_TEST
-+  if( sqlite3_current_time ){
-+    *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
-+  }
-+#endif
-+  UNUSED_PARAMETER(NotUsed);
-+  return rc;
-+}
- 
- /*
--** Macro to find the minimum of two numeric values.
-+** 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.
- */
--#ifndef MIN
--# define MIN(x,y) ((x)<(y)?(x):(y))
--#endif
-+static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){
-+  sqlite3_int64 i = 0;
-+  int rc;
-+  UNUSED_PARAMETER(NotUsed);
-+  rc = unixCurrentTimeInt64(0, &i);
-+  *prNow = i/86400000.0;
-+  return rc;
-+}
- 
- /*
--** Some Microsoft compilers lack this definition.
-+** We added the xGetLastError() method with the intention of providing
-+** better low-level error messages when operating-system problems come up
-+** during SQLite operation.  But so far, none of that has been implemented
-+** in the core.  So this routine is never called.  For now, it is merely
-+** a place-holder.
- */
--#ifndef INVALID_FILE_ATTRIBUTES
--# define INVALID_FILE_ATTRIBUTES ((DWORD)-1) 
--#endif
-+static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
-+  UNUSED_PARAMETER(NotUsed);
-+  UNUSED_PARAMETER(NotUsed2);
-+  UNUSED_PARAMETER(NotUsed3);
-+  return 0;
-+}
- 
--#ifndef FILE_FLAG_MASK
--# define FILE_FLAG_MASK          (0xFF3C0000)
--#endif
- 
--#ifndef FILE_ATTRIBUTE_MASK
--# define FILE_ATTRIBUTE_MASK     (0x0003FFF7)
--#endif
-+/*
-+************************ End of sqlite3_vfs methods ***************************
-+******************************************************************************/
- 
--#ifndef SQLITE_OMIT_WAL
--/* Forward references */
--typedef struct winShm winShm;           /* A connection to shared-memory */
--typedef struct winShmNode winShmNode;   /* A region of shared-memory */
--#endif
-+/******************************************************************************
-+************************** Begin Proxy Locking ********************************
-+**
-+** Proxy locking is a "uber-locking-method" in this sense:  It uses the
-+** other locking methods on secondary lock files.  Proxy locking is a
-+** meta-layer over top of the primitive locking implemented above.  For
-+** this reason, the division that implements of proxy locking is deferred
-+** until late in the file (here) after all of the other I/O methods have
-+** been defined - so that the primitive locking methods are available
-+** as services to help with the implementation of proxy locking.
-+**
-+****
-+**
-+** The default locking schemes in SQLite use byte-range locks on the
-+** database file to coordinate safe, concurrent access by multiple readers
-+** and writers [http://sqlite.org/lockingv3.html].  The five file locking
-+** states (UNLOCKED, PENDING, SHARED, RESERVED, EXCLUSIVE) are implemented
-+** as POSIX read & write locks over fixed set of locations (via fsctl),
-+** on AFP and SMB only exclusive byte-range locks are available via fsctl
-+** with _IOWR('z', 23, struct ByteRangeLockPB2) to track the same 5 states.
-+** To simulate a F_RDLCK on the shared range, on AFP a randomly selected
-+** address in the shared range is taken for a SHARED lock, the entire
-+** shared range is taken for an EXCLUSIVE lock):
-+**
-+**      PENDING_BYTE        0x40000000
-+**      RESERVED_BYTE       0x40000001
-+**      SHARED_RANGE        0x40000002 -> 0x40000200
-+**
-+** This works well on the local file system, but shows a nearly 100x
-+** slowdown in read performance on AFP because the AFP client disables
-+** the read cache when byte-range locks are present.  Enabling the read
-+** cache exposes a cache coherency problem that is present on all OS X
-+** supported network file systems.  NFS and AFP both observe the
-+** close-to-open semantics for ensuring cache coherency
-+** [http://nfs.sourceforge.net/#faq_a8], which does not effectively
-+** address the requirements for concurrent database access by multiple
-+** readers and writers
-+** [http://www.nabble.com/SQLite-on-NFS-cache-coherency-td15655701.html].
-+**
-+** To address the performance and cache coherency issues, proxy file locking
-+** changes the way database access is controlled by limiting access to a
-+** single host at a time and moving file locks off of the database file
-+** and onto a proxy file on the local file system.  
-+**
-+**
-+** Using proxy locks
-+** -----------------
-+**
-+** C APIs
-+**
-+**  sqlite3_file_control(db, dbname, SQLITE_SET_LOCKPROXYFILE,
-+**                       <proxy_path> | ":auto:");
-+**  sqlite3_file_control(db, dbname, SQLITE_GET_LOCKPROXYFILE, &<proxy_path>);
-+**
-+**
-+** SQL pragmas
-+**
-+**  PRAGMA [database.]lock_proxy_file=<proxy_path> | :auto:
-+**  PRAGMA [database.]lock_proxy_file
-+**
-+** Specifying ":auto:" means that if there is a conch file with a matching
-+** host ID in it, the proxy path in the conch file will be used, otherwise
-+** a proxy path based on the user's temp dir
-+** (via confstr(_CS_DARWIN_USER_TEMP_DIR,...)) will be used and the
-+** actual proxy file name is generated from the name and path of the
-+** database file.  For example:
-+**
-+**       For database path "/Users/me/foo.db" 
-+**       The lock path will be "<tmpdir>/sqliteplocks/_Users_me_foo.db:auto:")
-+**
-+** Once a lock proxy is configured for a database connection, it can not
-+** be removed, however it may be switched to a different proxy path via
-+** the above APIs (assuming the conch file is not being held by another
-+** connection or process). 
-+**
-+**
-+** How proxy locking works
-+** -----------------------
-+**
-+** Proxy file locking relies primarily on two new supporting files: 
-+**
-+**   *  conch file to limit access to the database file to a single host
-+**      at a time
-+**
-+**   *  proxy file to act as a proxy for the advisory locks normally
-+**      taken on the database
-+**
-+** The conch file - to use a proxy file, sqlite must first "hold the conch"
-+** by taking an sqlite-style shared lock on the conch file, reading the
-+** contents and comparing the host's unique host ID (see below) and lock
-+** 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
-+** 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
-+** is held by another process (with a shared lock), the exclusive lock
-+** will fail and SQLITE_BUSY is returned.
-+**
-+** The proxy file - a single-byte file used for all advisory file locks
-+** normally taken on the database file.   This allows for safe sharing
-+** of the database file for multiple readers and writers on the same
-+** host (the conch ensures that they all use the same local lock file).
-+**
-+** Requesting the lock proxy does not immediately take the conch, it is
-+** only taken when the first request to lock database file is made.  
-+** This matches the semantics of the traditional locking behavior, where
-+** opening a connection to a database file does not take a lock on it.
-+** The shared lock and an open file descriptor are maintained until 
-+** the connection to the database is closed. 
-+**
-+** The proxy file and the lock file are never deleted so they only need
-+** to be created the first time they are used.
-+**
-+** Configuration options
-+** ---------------------
-+**
-+**  SQLITE_PREFER_PROXY_LOCKING
-+**
-+**       Database files accessed on non-local file systems are
-+**       automatically configured for proxy locking, lock files are
-+**       named automatically using the same logic as
-+**       PRAGMA lock_proxy_file=":auto:"
-+**    
-+**  SQLITE_PROXY_DEBUG
-+**
-+**       Enables the logging of error messages during host id file
-+**       retrieval and creation
-+**
-+**  LOCKPROXYDIR
-+**
-+**       Overrides the default directory used for lock proxy files that
-+**       are named automatically via the ":auto:" setting
-+**
-+**  SQLITE_DEFAULT_PROXYDIR_PERMISSIONS
-+**
-+**       Permissions to use when creating a directory for storing the
-+**       lock proxy files, only used when LOCKPROXYDIR is not set.
-+**    
-+**    
-+** As mentioned above, when compiled with SQLITE_PREFER_PROXY_LOCKING,
-+** 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
-+** sqlite_file_control API is not affected by SQLITE_FORCE_PROXY_LOCKING).
-+*/
- 
- /*
--** WinCE lacks native support for file locking so we have to fake it
--** with some code of our own.
-+** Proxy locking is only available on MacOSX 
- */
--#if SQLITE_OS_WINCE
--typedef struct winceLock {
--  int nReaders;       /* Number of reader locks obtained */
--  BOOL bPending;      /* Indicates a pending lock has been obtained */
--  BOOL bReserved;     /* Indicates a reserved lock has been obtained */
--  BOOL bExclusive;    /* Indicates an exclusive lock has been obtained */
--} winceLock;
--#endif
-+#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
- 
- /*
--** The winFile structure is a subclass of sqlite3_file* specific to the win32
--** portability layer.
-+** The proxyLockingContext has the path and file structures for the remote 
-+** and local proxy files in it
- */
--typedef struct winFile winFile;
--struct winFile {
--  const sqlite3_io_methods *pMethod; /*** Must be first ***/
--  sqlite3_vfs *pVfs;      /* The VFS used to open this file */
--  HANDLE h;               /* Handle for accessing the file */
--  u8 locktype;            /* Type of lock currently held on this file */
--  short sharedLockByte;   /* Randomly chosen byte used as a shared lock */
--  u8 ctrlFlags;           /* Flags.  See WINFILE_* below */
--  DWORD lastErrno;        /* The Windows errno from the last I/O error */
--#ifndef SQLITE_OMIT_WAL
--  winShm *pShm;           /* Instance of shared memory on this file */
--#endif
--  const char *zPath;      /* Full pathname of this file */
--  int szChunk;            /* Chunk size configured by FCNTL_CHUNK_SIZE */
--#if SQLITE_OS_WINCE
--  LPWSTR zDeleteOnClose;  /* Name of file to delete when closing */
--  HANDLE hMutex;          /* Mutex used to control access to shared lock */  
--  HANDLE hShared;         /* Shared memory segment used for locking */
--  winceLock local;        /* Locks obtained by this instance of winFile */
--  winceLock *shared;      /* Global shared lock memory for the file  */
--#endif
--#if SQLITE_MAX_MMAP_SIZE>0
--  int nFetchOut;                /* Number of outstanding xFetch references */
--  HANDLE hMap;                  /* Handle for accessing memory mapping */
--  void *pMapRegion;             /* Area memory mapped */
--  sqlite3_int64 mmapSize;       /* Usable size of mapped region */
--  sqlite3_int64 mmapSizeActual; /* Actual size of mapped region */
--  sqlite3_int64 mmapSizeMax;    /* Configured FCNTL_MMAP_SIZE value */
--#endif
-+typedef struct proxyLockingContext proxyLockingContext;
-+struct proxyLockingContext {
-+  unixFile *conchFile;         /* Open conch file */
-+  char *conchFilePath;         /* Name of the conch file */
-+  unixFile *lockProxy;         /* Open proxy lock file */
-+  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 */
-+  void *oldLockingContext;     /* Original lockingcontext to restore on close */
-+  sqlite3_io_methods const *pOldMethod;     /* Original I/O methods for close */
- };
- 
--/*
--** Allowed values for winFile.ctrlFlags
-+/* 
-+** The proxy lock file path for the database at dbPath is written into lPath, 
-+** which must point to valid, writable memory large enough for a maxLen length
-+** file path. 
- */
--#define WINFILE_RDONLY          0x02   /* Connection is read only */
--#define WINFILE_PERSIST_WAL     0x04   /* Persistent WAL mode */
--#define WINFILE_PSOW            0x10   /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
-+static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){
-+  int len;
-+  int dbLen;
-+  int i;
- 
--/*
-- * The size of the buffer used by sqlite3_win32_write_debug().
-- */
--#ifndef SQLITE_WIN32_DBG_BUF_SIZE
--#  define SQLITE_WIN32_DBG_BUF_SIZE   ((int)(4096-sizeof(DWORD)))
-+#ifdef LOCKPROXYDIR
-+  len = strlcpy(lPath, LOCKPROXYDIR, maxLen);
-+#else
-+# ifdef _CS_DARWIN_USER_TEMP_DIR
-+  {
-+    if( !confstr(_CS_DARWIN_USER_TEMP_DIR, lPath, maxLen) ){
-+      OSTRACE(("GETLOCKPATH  failed %s errno=%d pid=%d\n",
-+               lPath, errno, getpid()));
-+      return SQLITE_IOERR_LOCK;
-+    }
-+    len = strlcat(lPath, "sqliteplocks", maxLen);    
-+  }
-+# else
-+  len = strlcpy(lPath, "/tmp/", maxLen);
-+# endif
- #endif
- 
--/*
-- * The value used with sqlite3_win32_set_directory() to specify that
-- * the data directory should be changed.
-- */
--#ifndef SQLITE_WIN32_DATA_DIRECTORY_TYPE
--#  define SQLITE_WIN32_DATA_DIRECTORY_TYPE (1)
--#endif
-+  if( lPath[len-1]!='/' ){
-+    len = strlcat(lPath, "/", maxLen);
-+  }
-+  
-+  /* transform the db path to a unique cache name */
-+  dbLen = (int)strlen(dbPath);
-+  for( i=0; i<dbLen && (i+len+7)<(int)maxLen; i++){
-+    char c = dbPath[i];
-+    lPath[i+len] = (c=='/')?'_':c;
-+  }
-+  lPath[i+len]='\0';
-+  strlcat(lPath, ":auto:", maxLen);
-+  OSTRACE(("GETLOCKPATH  proxy lock path=%s pid=%d\n", lPath, getpid()));
-+  return SQLITE_OK;
-+}
- 
--/*
-- * The value used with sqlite3_win32_set_directory() to specify that
-- * the temporary directory should be changed.
-+/* 
-+ ** Creates the lock file and any missing directories in lockPath
-  */
--#ifndef SQLITE_WIN32_TEMP_DIRECTORY_TYPE
--#  define SQLITE_WIN32_TEMP_DIRECTORY_TYPE (2)
--#endif
-+static int proxyCreateLockPath(const char *lockPath){
-+  int i, len;
-+  char buf[MAXPATHLEN];
-+  int start = 0;
-+  
-+  assert(lockPath!=NULL);
-+  /* try to create all the intermediate directories */
-+  len = (int)strlen(lockPath);
-+  buf[0] = lockPath[0];
-+  for( i=1; i<len; i++ ){
-+    if( lockPath[i] == '/' && (i - start > 0) ){
-+      /* only mkdir if leaf dir != "." or "/" or ".." */
-+      if( i-start>2 || (i-start==1 && buf[start] != '.' && buf[start] != '/') 
-+         || (i-start==2 && buf[start] != '.' && buf[start+1] != '.') ){
-+        buf[i]='\0';
-+        if( osMkdir(buf, SQLITE_DEFAULT_PROXYDIR_PERMISSIONS) ){
-+          int err=errno;
-+          if( err!=EEXIST ) {
-+            OSTRACE(("CREATELOCKPATH  FAILED creating %s, "
-+                     "'%s' proxy lock path=%s pid=%d\n",
-+                     buf, strerror(err), lockPath, getpid()));
-+            return err;
-+          }
-+        }
-+      }
-+      start=i+1;
-+    }
-+    buf[i] = lockPath[i];
-+  }
-+  OSTRACE(("CREATELOCKPATH  proxy lock path=%s pid=%d\n", lockPath, getpid()));
-+  return 0;
-+}
- 
- /*
-- * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the
-- * various Win32 API heap functions instead of our own.
-- */
--#ifdef SQLITE_WIN32_MALLOC
-+** Create a new VFS file descriptor (stored in memory obtained from
-+** sqlite3_malloc) and open the file named "path" in the file descriptor.
-+**
-+** The caller is responsible not only for closing the file descriptor
-+** but also for freeing the memory associated with the file descriptor.
-+*/
-+static int proxyCreateUnixFile(
-+    const char *path,        /* path for the new unixFile */
-+    unixFile **ppFile,       /* unixFile created and returned by ref */
-+    int islockfile           /* if non zero missing dirs will be created */
-+) {
-+  int fd = -1;
-+  unixFile *pNew;
-+  int rc = SQLITE_OK;
-+  int openFlags = O_RDWR | O_CREAT;
-+  sqlite3_vfs dummyVfs;
-+  int terrno = 0;
-+  UnixUnusedFd *pUnused = NULL;
- 
--/*
-- * If this is non-zero, an isolated heap will be created by the native Win32
-- * allocator subsystem; otherwise, the default process heap will be used.  This
-- * setting has no effect when compiling for WinRT.  By default, this is enabled
-- * and an isolated heap will be created to store all allocated data.
-- *
-- ******************************************************************************
-- * WARNING: It is important to note that when this setting is non-zero and the
-- *          winMemShutdown function is called (e.g. by the sqlite3_shutdown
-- *          function), all data that was allocated using the isolated heap will
-- *          be freed immediately and any attempt to access any of that freed
-- *          data will almost certainly result in an immediate access violation.
-- ******************************************************************************
-- */
--#ifndef SQLITE_WIN32_HEAP_CREATE
--#  define SQLITE_WIN32_HEAP_CREATE    (TRUE)
-+  /* 1. first try to open/create the file
-+  ** 2. if that fails, and this is a lock file (not-conch), try creating
-+  ** the parent directories and then try again.
-+  ** 3. if that fails, try to open the file read-only
-+  ** otherwise return BUSY (if lock file) or CANTOPEN for the conch file
-+  */
-+  pUnused = findReusableFd(path, openFlags);
-+  if( pUnused ){
-+    fd = pUnused->fd;
-+  }else{
-+    pUnused = sqlite3_malloc(sizeof(*pUnused));
-+    if( !pUnused ){
-+      return SQLITE_NOMEM;
-+    }
-+  }
-+  if( fd<0 ){
-+    fd = robust_open(path, openFlags, 0);
-+    terrno = errno;
-+    if( fd<0 && errno==ENOENT && islockfile ){
-+      if( proxyCreateLockPath(path) == SQLITE_OK ){
-+        fd = robust_open(path, openFlags, 0);
-+      }
-+    }
-+  }
-+  if( fd<0 ){
-+    openFlags = O_RDONLY;
-+    fd = robust_open(path, openFlags, 0);
-+    terrno = errno;
-+  }
-+  if( fd<0 ){
-+    if( islockfile ){
-+      return SQLITE_BUSY;
-+    }
-+    switch (terrno) {
-+      case EACCES:
-+        return SQLITE_PERM;
-+      case EIO: 
-+        return SQLITE_IOERR_LOCK; /* even though it is the conch */
-+      default:
-+        return SQLITE_CANTOPEN_BKPT;
-+    }
-+  }
-+  
-+  pNew = (unixFile *)sqlite3_malloc(sizeof(*pNew));
-+  if( pNew==NULL ){
-+    rc = SQLITE_NOMEM;
-+    goto end_create_proxy;
-+  }
-+  memset(pNew, 0, sizeof(unixFile));
-+  pNew->openFlags = openFlags;
-+  memset(&dummyVfs, 0, sizeof(dummyVfs));
-+  dummyVfs.pAppData = (void*)&autolockIoFinder;
-+  dummyVfs.zName = "dummy";
-+  pUnused->fd = fd;
-+  pUnused->flags = openFlags;
-+  pNew->pUnused = pUnused;
-+  
-+  rc = fillInUnixFile(&dummyVfs, fd, (sqlite3_file*)pNew, path, 0);
-+  if( rc==SQLITE_OK ){
-+    *ppFile = pNew;
-+    return SQLITE_OK;
-+  }
-+end_create_proxy:    
-+  robust_close(pNew, fd, __LINE__);
-+  sqlite3_free(pNew);
-+  sqlite3_free(pUnused);
-+  return rc;
-+}
-+
-+#ifdef SQLITE_TEST
-+/* simulate multiple hosts by creating unique hostid file paths */
-+SQLITE_API int sqlite3_hostid_num = 0;
- #endif
- 
--/*
-- * The initial size of the Win32-specific heap.  This value may be zero.
-- */
--#ifndef SQLITE_WIN32_HEAP_INIT_SIZE
--#  define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_DEFAULT_CACHE_SIZE) * \
--                                       (SQLITE_DEFAULT_PAGE_SIZE) + 4194304)
-+#define PROXY_HOSTIDLEN    16  /* conch file host id length */
-+
-+/* Not always defined in the headers as it ought to be */
-+extern int gethostuuid(uuid_t id, const struct timespec *wait);
-+
-+/* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN 
-+** bytes of writable memory.
-+*/
-+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
-+  {
-+    static const struct timespec timeout = {1, 0}; /* 1 sec timeout */
-+    if( gethostuuid(pHostID, &timeout) ){
-+      int err = errno;
-+      if( pError ){
-+        *pError = err;
-+      }
-+      return SQLITE_IOERR;
-+    }
-+  }
-+#else
-+  UNUSED_PARAMETER(pError);
- #endif
--
--/*
-- * The maximum size of the Win32-specific heap.  This value may be zero.
-- */
--#ifndef SQLITE_WIN32_HEAP_MAX_SIZE
--#  define SQLITE_WIN32_HEAP_MAX_SIZE  (0)
-+#ifdef SQLITE_TEST
-+  /* simulate multiple hosts by creating unique hostid file paths */
-+  if( sqlite3_hostid_num != 0){
-+    pHostID[0] = (char)(pHostID[0] + (char)(sqlite3_hostid_num & 0xFF));
-+  }
- #endif
-+  
-+  return SQLITE_OK;
-+}
- 
--/*
-- * The extra flags to use in calls to the Win32 heap APIs.  This value may be
-- * zero for the default behavior.
-+/* The conch file contains the header, host id and lock file path
-  */
--#ifndef SQLITE_WIN32_HEAP_FLAGS
--#  define SQLITE_WIN32_HEAP_FLAGS     (0)
--#endif
-+#define PROXY_CONCHVERSION 2   /* 1-byte header, 16-byte host id, path */
-+#define PROXY_HEADERLEN    1   /* conch file header length */
-+#define PROXY_PATHINDEX    (PROXY_HEADERLEN+PROXY_HOSTIDLEN)
-+#define PROXY_MAXCONCHLEN  (PROXY_HEADERLEN+PROXY_HOSTIDLEN+MAXPATHLEN)
- 
--/*
--** The winMemData structure stores information required by the Win32-specific
--** sqlite3_mem_methods implementation.
-+/* 
-+** Takes an open conch file, copies the contents to a new path and then moves 
-+** it back.  The newly created file's file descriptor is assigned to the
-+** conch file structure and finally the original conch file descriptor is 
-+** closed.  Returns zero if successful.
- */
--typedef struct winMemData winMemData;
--struct winMemData {
--#ifndef NDEBUG
--  u32 magic;    /* Magic number to detect structure corruption. */
--#endif
--  HANDLE hHeap; /* The handle to our heap. */
--  BOOL bOwned;  /* Do we own the heap (i.e. destroy it on shutdown)? */
--};
-+static int proxyBreakConchLock(unixFile *pFile, uuid_t myHostID){
-+  proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; 
-+  unixFile *conchFile = pCtx->conchFile;
-+  char tPath[MAXPATHLEN];
-+  char buf[PROXY_MAXCONCHLEN];
-+  char *cPath = pCtx->conchFilePath;
-+  size_t readLen = 0;
-+  size_t pathLen = 0;
-+  char errmsg[64] = "";
-+  int fd = -1;
-+  int rc = -1;
-+  UNUSED_PARAMETER(myHostID);
- 
--#ifndef NDEBUG
--#define WINMEM_MAGIC     0x42b2830b
--#endif
-+  /* create a new path by replace the trailing '-conch' with '-break' */
-+  pathLen = strlcpy(tPath, cPath, MAXPATHLEN);
-+  if( pathLen>MAXPATHLEN || pathLen<6 || 
-+     (strlcpy(&tPath[pathLen-5], "break", 6) != 5) ){
-+    sqlite3_snprintf(sizeof(errmsg),errmsg,"path error (len %d)",(int)pathLen);
-+    goto end_breaklock;
-+  }
-+  /* read the conch content */
-+  readLen = osPread(conchFile->h, buf, PROXY_MAXCONCHLEN, 0);
-+  if( readLen<PROXY_PATHINDEX ){
-+    sqlite3_snprintf(sizeof(errmsg),errmsg,"read error (len %d)",(int)readLen);
-+    goto end_breaklock;
-+  }
-+  /* write it out to the temporary break file */
-+  fd = robust_open(tPath, (O_RDWR|O_CREAT|O_EXCL), 0);
-+  if( fd<0 ){
-+    sqlite3_snprintf(sizeof(errmsg), errmsg, "create failed (%d)", errno);
-+    goto end_breaklock;
-+  }
-+  if( osPwrite(fd, buf, readLen, 0) != (ssize_t)readLen ){
-+    sqlite3_snprintf(sizeof(errmsg), errmsg, "write failed (%d)", errno);
-+    goto end_breaklock;
-+  }
-+  if( rename(tPath, cPath) ){
-+    sqlite3_snprintf(sizeof(errmsg), errmsg, "rename failed (%d)", errno);
-+    goto end_breaklock;
-+  }
-+  rc = 0;
-+  fprintf(stderr, "broke stale lock on %s\n", cPath);
-+  robust_close(pFile, conchFile->h, __LINE__);
-+  conchFile->h = fd;
-+  conchFile->openFlags = O_RDWR | O_CREAT;
- 
--static struct winMemData win_mem_data = {
--#ifndef NDEBUG
--  WINMEM_MAGIC,
--#endif
--  NULL, FALSE
--};
-+end_breaklock:
-+  if( rc ){
-+    if( fd>=0 ){
-+      osUnlink(tPath);
-+      robust_close(pFile, fd, __LINE__);
-+    }
-+    fprintf(stderr, "failed to break stale lock on %s, %s\n", cPath, errmsg);
-+  }
-+  return rc;
-+}
- 
--#ifndef NDEBUG
--#define winMemAssertMagic() assert( win_mem_data.magic==WINMEM_MAGIC )
--#else
--#define winMemAssertMagic()
--#endif
-+/* Take the requested lock on the conch file and break a stale lock if the 
-+** host id matches.
-+*/
-+static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){
-+  proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; 
-+  unixFile *conchFile = pCtx->conchFile;
-+  int rc = SQLITE_OK;
-+  int nTries = 0;
-+  struct timespec conchModTime;
-+  
-+  memset(&conchModTime, 0, sizeof(conchModTime));
-+  do {
-+    rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType);
-+    nTries ++;
-+    if( rc==SQLITE_BUSY ){
-+      /* If the lock failed (busy):
-+       * 1st try: get the mod time of the conch, wait 0.5s and try again. 
-+       * 2nd try: fail if the mod time changed or host id is different, wait 
-+       *           10 sec and try again
-+       * 3rd try: break the lock unless the mod time has changed.
-+       */
-+      struct stat buf;
-+      if( osFstat(conchFile->h, &buf) ){
-+        pFile->lastErrno = errno;
-+        return SQLITE_IOERR_LOCK;
-+      }
-+      
-+      if( nTries==1 ){
-+        conchModTime = buf.st_mtimespec;
-+        usleep(500000); /* wait 0.5 sec and try the lock again*/
-+        continue;  
-+      }
- 
--#define winMemGetHeap() win_mem_data.hHeap
-+      assert( nTries>1 );
-+      if( conchModTime.tv_sec != buf.st_mtimespec.tv_sec || 
-+         conchModTime.tv_nsec != buf.st_mtimespec.tv_nsec ){
-+        return SQLITE_BUSY;
-+      }
-+      
-+      if( nTries==2 ){  
-+        char tBuf[PROXY_MAXCONCHLEN];
-+        int len = osPread(conchFile->h, tBuf, PROXY_MAXCONCHLEN, 0);
-+        if( len<0 ){
-+          pFile->lastErrno = errno;
-+          return SQLITE_IOERR_LOCK;
-+        }
-+        if( len>PROXY_PATHINDEX && tBuf[0]==(char)PROXY_CONCHVERSION){
-+          /* don't break the lock if the host id doesn't match */
-+          if( 0!=memcmp(&tBuf[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN) ){
-+            return SQLITE_BUSY;
-+          }
-+        }else{
-+          /* don't break the lock on short read or a version mismatch */
-+          return SQLITE_BUSY;
-+        }
-+        usleep(10000000); /* wait 10 sec and try the lock again */
-+        continue; 
-+      }
-+      
-+      assert( nTries==3 );
-+      if( 0==proxyBreakConchLock(pFile, myHostID) ){
-+        rc = SQLITE_OK;
-+        if( lockType==EXCLUSIVE_LOCK ){
-+          rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK);          
-+        }
-+        if( !rc ){
-+          rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType);
-+        }
-+      }
-+    }
-+  } while( rc==SQLITE_BUSY && nTries<3 );
-+  
-+  return rc;
-+}
- 
--static void *winMemMalloc(int nBytes);
--static void winMemFree(void *pPrior);
--static void *winMemRealloc(void *pPrior, int nBytes);
--static int winMemSize(void *p);
--static int winMemRoundup(int n);
--static int winMemInit(void *pAppData);
--static void winMemShutdown(void *pAppData);
-+/* Takes the conch by taking a shared lock and read the contents conch, if 
-+** lockPath is non-NULL, the host ID and lock file path must match.  A NULL 
-+** lockPath means that the lockPath in the conch file will be used if the 
-+** host IDs match, or a new lock path will be generated automatically 
-+** and written to the conch file.
-+*/
-+static int proxyTakeConch(unixFile *pFile){
-+  proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; 
-+  
-+  if( pCtx->conchHeld!=0 ){
-+    return SQLITE_OK;
-+  }else{
-+    unixFile *conchFile = pCtx->conchFile;
-+    uuid_t myHostID;
-+    int pError = 0;
-+    char readBuf[PROXY_MAXCONCHLEN];
-+    char lockPath[MAXPATHLEN];
-+    char *tempLockPath = NULL;
-+    int rc = SQLITE_OK;
-+    int createConch = 0;
-+    int hostIdMatch = 0;
-+    int readLen = 0;
-+    int tryOldLockPath = 0;
-+    int forceNewLockPath = 0;
-+    
-+    OSTRACE(("TAKECONCH  %d for %s pid=%d\n", conchFile->h,
-+             (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), getpid()));
- 
--SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetWin32(void);
--#endif /* SQLITE_WIN32_MALLOC */
-+    rc = proxyGetHostID(myHostID, &pError);
-+    if( (rc&0xff)==SQLITE_IOERR ){
-+      pFile->lastErrno = pError;
-+      goto end_takeconch;
-+    }
-+    rc = proxyConchLock(pFile, myHostID, SHARED_LOCK);
-+    if( rc!=SQLITE_OK ){
-+      goto end_takeconch;
-+    }
-+    /* read the existing conch file */
-+    readLen = seekAndRead((unixFile*)conchFile, 0, readBuf, PROXY_MAXCONCHLEN);
-+    if( readLen<0 ){
-+      /* I/O error: lastErrno set by seekAndRead */
-+      pFile->lastErrno = conchFile->lastErrno;
-+      rc = SQLITE_IOERR_READ;
-+      goto end_takeconch;
-+    }else if( readLen<=(PROXY_HEADERLEN+PROXY_HOSTIDLEN) || 
-+             readBuf[0]!=(char)PROXY_CONCHVERSION ){
-+      /* a short read or version format mismatch means we need to create a new 
-+      ** conch file. 
-+      */
-+      createConch = 1;
-+    }
-+    /* if the host id matches and the lock path already exists in the conch
-+    ** we'll try to use the path there, if we can't open that path, we'll 
-+    ** retry with a new auto-generated path 
-+    */
-+    do { /* in case we need to try again for an :auto: named lock file */
- 
--/*
--** The following variable is (normally) set once and never changes
--** thereafter.  It records whether the operating system is Win9x
--** or WinNT.
--**
--** 0:   Operating system unknown.
--** 1:   Operating system is Win9x.
--** 2:   Operating system is WinNT.
--**
--** In order to facilitate testing on a WinNT system, the test fixture
--** can manually set this value to 1 to emulate Win98 behavior.
--*/
--#ifdef SQLITE_TEST
--SQLITE_API int sqlite3_os_type = 0;
-+      if( !createConch && !forceNewLockPath ){
-+        hostIdMatch = !memcmp(&readBuf[PROXY_HEADERLEN], myHostID, 
-+                                  PROXY_HOSTIDLEN);
-+        /* if the conch has data compare the contents */
-+        if( !pCtx->lockProxyPath ){
-+          /* for auto-named local lock file, just check the host ID and we'll
-+           ** use the local lock file path that's already in there
-+           */
-+          if( hostIdMatch ){
-+            size_t pathLen = (readLen - PROXY_PATHINDEX);
-+            
-+            if( pathLen>=MAXPATHLEN ){
-+              pathLen=MAXPATHLEN-1;
-+            }
-+            memcpy(lockPath, &readBuf[PROXY_PATHINDEX], pathLen);
-+            lockPath[pathLen] = 0;
-+            tempLockPath = lockPath;
-+            tryOldLockPath = 1;
-+            /* create a copy of the lock path if the conch is taken */
-+            goto end_takeconch;
-+          }
-+        }else if( hostIdMatch
-+               && !strncmp(pCtx->lockProxyPath, &readBuf[PROXY_PATHINDEX],
-+                           readLen-PROXY_PATHINDEX)
-+        ){
-+          /* conch host and lock path match */
-+          goto end_takeconch; 
-+        }
-+      }
-+      
-+      /* if the conch isn't writable and doesn't match, we can't take it */
-+      if( (conchFile->openFlags&O_RDWR) == 0 ){
-+        rc = SQLITE_BUSY;
-+        goto end_takeconch;
-+      }
-+      
-+      /* either the conch didn't match or we need to create a new one */
-+      if( !pCtx->lockProxyPath ){
-+        proxyGetLockPath(pCtx->dbPath, lockPath, MAXPATHLEN);
-+        tempLockPath = lockPath;
-+        /* create a copy of the lock path _only_ if the conch is taken */
-+      }
-+      
-+      /* update conch with host and path (this will fail if other process
-+      ** has a shared lock already), if the host id matches, use the big
-+      ** stick.
-+      */
-+      futimes(conchFile->h, NULL);
-+      if( hostIdMatch && !createConch ){
-+        if( conchFile->pInode && conchFile->pInode->nShared>1 ){
-+          /* We are trying for an exclusive lock but another thread in this
-+           ** same process is still holding a shared lock. */
-+          rc = SQLITE_BUSY;
-+        } else {          
-+          rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK);
-+        }
-+      }else{
-+        rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, EXCLUSIVE_LOCK);
-+      }
-+      if( rc==SQLITE_OK ){
-+        char writeBuffer[PROXY_MAXCONCHLEN];
-+        int writeSize = 0;
-+        
-+        writeBuffer[0] = (char)PROXY_CONCHVERSION;
-+        memcpy(&writeBuffer[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN);
-+        if( pCtx->lockProxyPath!=NULL ){
-+          strlcpy(&writeBuffer[PROXY_PATHINDEX], pCtx->lockProxyPath, MAXPATHLEN);
-+        }else{
-+          strlcpy(&writeBuffer[PROXY_PATHINDEX], tempLockPath, MAXPATHLEN);
-+        }
-+        writeSize = PROXY_PATHINDEX + strlen(&writeBuffer[PROXY_PATHINDEX]);
-+        robust_ftruncate(conchFile->h, writeSize);
-+        rc = unixWrite((sqlite3_file *)conchFile, writeBuffer, writeSize, 0);
-+        fsync(conchFile->h);
-+        /* If we created a new conch file (not just updated the contents of a 
-+         ** valid conch file), try to match the permissions of the database 
-+         */
-+        if( rc==SQLITE_OK && createConch ){
-+          struct stat buf;
-+          int err = osFstat(pFile->h, &buf);
-+          if( err==0 ){
-+            mode_t cmode = buf.st_mode&(S_IRUSR|S_IWUSR | S_IRGRP|S_IWGRP |
-+                                        S_IROTH|S_IWOTH);
-+            /* try to match the database file R/W permissions, ignore failure */
-+#ifndef SQLITE_PROXY_DEBUG
-+            osFchmod(conchFile->h, cmode);
- #else
--static int sqlite3_os_type = 0;
--#endif
--
--#ifndef SYSCALL
--#  define SYSCALL sqlite3_syscall_ptr
-+            do{
-+              rc = osFchmod(conchFile->h, cmode);
-+            }while( rc==(-1) && errno==EINTR );
-+            if( rc!=0 ){
-+              int code = errno;
-+              fprintf(stderr, "fchmod %o FAILED with %d %s\n",
-+                      cmode, code, strerror(code));
-+            } else {
-+              fprintf(stderr, "fchmod %o SUCCEDED\n",cmode);
-+            }
-+          }else{
-+            int code = errno;
-+            fprintf(stderr, "STAT FAILED[%d] with %d %s\n", 
-+                    err, code, strerror(code));
- #endif
-+          }
-+        }
-+      }
-+      conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, SHARED_LOCK);
-+      
-+    end_takeconch:
-+      OSTRACE(("TRANSPROXY: CLOSE  %d\n", pFile->h));
-+      if( rc==SQLITE_OK && pFile->openFlags ){
-+        int fd;
-+        if( pFile->h>=0 ){
-+          robust_close(pFile, pFile->h, __LINE__);
-+        }
-+        pFile->h = -1;
-+        fd = robust_open(pCtx->dbPath, pFile->openFlags, 0);
-+        OSTRACE(("TRANSPROXY: OPEN  %d\n", fd));
-+        if( fd>=0 ){
-+          pFile->h = fd;
-+        }else{
-+          rc=SQLITE_CANTOPEN_BKPT; /* SQLITE_BUSY? proxyTakeConch called
-+           during locking */
-+        }
-+      }
-+      if( rc==SQLITE_OK && !pCtx->lockProxy ){
-+        char *path = tempLockPath ? tempLockPath : pCtx->lockProxyPath;
-+        rc = proxyCreateUnixFile(path, &pCtx->lockProxy, 1);
-+        if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM && tryOldLockPath ){
-+          /* we couldn't create the proxy lock file with the old lock file path
-+           ** so try again via auto-naming 
-+           */
-+          forceNewLockPath = 1;
-+          tryOldLockPath = 0;
-+          continue; /* go back to the do {} while start point, try again */
-+        }
-+      }
-+      if( rc==SQLITE_OK ){
-+        /* Need to make a copy of path if we extracted the value
-+         ** from the conch file or the path was allocated on the stack
-+         */
-+        if( tempLockPath ){
-+          pCtx->lockProxyPath = sqlite3DbStrDup(0, tempLockPath);
-+          if( !pCtx->lockProxyPath ){
-+            rc = SQLITE_NOMEM;
-+          }
-+        }
-+      }
-+      if( rc==SQLITE_OK ){
-+        pCtx->conchHeld = 1;
-+        
-+        if( pCtx->lockProxy->pMethod == &afpIoMethods ){
-+          afpLockingContext *afpCtx;
-+          afpCtx = (afpLockingContext *)pCtx->lockProxy->lockingContext;
-+          afpCtx->dbPath = pCtx->lockProxyPath;
-+        }
-+      } else {
-+        conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK);
-+      }
-+      OSTRACE(("TAKECONCH  %d %s\n", conchFile->h,
-+               rc==SQLITE_OK?"ok":"failed"));
-+      return rc;
-+    } while (1); /* in case we need to retry the :auto: lock file - 
-+                 ** we should never get here except via the 'continue' call. */
-+  }
-+}
- 
- /*
--** This function is not available on Windows CE or WinRT.
-- */
-+** If pFile holds a lock on a conch file, then release that lock.
-+*/
-+static int proxyReleaseConch(unixFile *pFile){
-+  int rc = SQLITE_OK;         /* Subroutine return code */
-+  proxyLockingContext *pCtx;  /* The locking context for the proxy lock */
-+  unixFile *conchFile;        /* Name of the conch file */
- 
--#if SQLITE_OS_WINCE || SQLITE_OS_WINRT
--#  define osAreFileApisANSI()       1
--#endif
-+  pCtx = (proxyLockingContext *)pFile->lockingContext;
-+  conchFile = pCtx->conchFile;
-+  OSTRACE(("RELEASECONCH  %d for %s pid=%d\n", conchFile->h,
-+           (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), 
-+           getpid()));
-+  if( pCtx->conchHeld>0 ){
-+    rc = conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK);
-+  }
-+  pCtx->conchHeld = 0;
-+  OSTRACE(("RELEASECONCH  %d %s\n", conchFile->h,
-+           (rc==SQLITE_OK ? "ok" : "failed")));
-+  return rc;
-+}
- 
- /*
--** Many system calls are accessed through pointer-to-functions so that
--** they may be overridden at runtime to facilitate fault injection during
--** testing and sandboxing.  The following array holds the names and pointers
--** to all overrideable system calls.
-+** Given the name of a database file, compute the name of its conch file.
-+** Store the conch filename in memory obtained from sqlite3_malloc().
-+** Make *pConchPath point to the new name.  Return SQLITE_OK on success
-+** or SQLITE_NOMEM if unable to obtain memory.
-+**
-+** The caller is responsible for ensuring that the allocated memory
-+** space is eventually freed.
-+**
-+** *pConchPath is set to NULL if a memory allocation error occurs.
- */
--static struct win_syscall {
--  const char *zName;            /* Name of the system call */
--  sqlite3_syscall_ptr pCurrent; /* Current value of the system call */
--  sqlite3_syscall_ptr pDefault; /* Default value */
--} aSyscall[] = {
--#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
-+static int proxyCreateConchPathname(char *dbPath, char **pConchPath){
-+  int i;                        /* Loop counter */
-+  int len = (int)strlen(dbPath); /* Length of database filename - dbPath */
-+  char *conchPath;              /* buffer in which to construct conch name */
- 
--#define osCharLowerW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[1].pCurrent)
-+  /* 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);
-+  if( conchPath==0 ){
-+    return SQLITE_NOMEM;
-+  }
-+  memcpy(conchPath, dbPath, len+1);
-+  
-+  /* now insert a "." before the last / character */
-+  for( i=(len-1); i>=0; i-- ){
-+    if( conchPath[i]=='/' ){
-+      i++;
-+      break;
-+    }
-+  }
-+  conchPath[i]='.';
-+  while ( i<len ){
-+    conchPath[i+1]=dbPath[i];
-+    i++;
-+  }
- 
--#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE)
--  { "CharUpperW",              (SYSCALL)CharUpperW,              0 },
--#else
--  { "CharUpperW",              (SYSCALL)0,                       0 },
--#endif
-+  /* append the "-conch" suffix to the file */
-+  memcpy(&conchPath[i+1], "-conch", 7);
-+  assert( (int)strlen(conchPath) == len+7 );
- 
--#define osCharUpperW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[2].pCurrent)
-+  return SQLITE_OK;
-+}
- 
--  { "CloseHandle",             (SYSCALL)CloseHandle,             0 },
- 
--#define osCloseHandle ((BOOL(WINAPI*)(HANDLE))aSyscall[3].pCurrent)
-+/* Takes a fully configured proxy locking-style unix file and switches
-+** the local lock file path 
-+*/
-+static int switchLockProxyPath(unixFile *pFile, const char *path) {
-+  proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext;
-+  char *oldPath = pCtx->lockProxyPath;
-+  int rc = SQLITE_OK;
- 
--#if defined(SQLITE_WIN32_HAS_ANSI)
--  { "CreateFileA",             (SYSCALL)CreateFileA,             0 },
--#else
--  { "CreateFileA",             (SYSCALL)0,                       0 },
--#endif
-+  if( pFile->eFileLock!=NO_LOCK ){
-+    return SQLITE_BUSY;
-+  }  
- 
--#define osCreateFileA ((HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD, \
--        LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[4].pCurrent)
-+  /* nothing to do if the path is NULL, :auto: or matches the existing path */
-+  if( !path || path[0]=='\0' || !strcmp(path, ":auto:") ||
-+    (oldPath && !strncmp(oldPath, path, MAXPATHLEN)) ){
-+    return SQLITE_OK;
-+  }else{
-+    unixFile *lockProxy = pCtx->lockProxy;
-+    pCtx->lockProxy=NULL;
-+    pCtx->conchHeld = 0;
-+    if( lockProxy!=NULL ){
-+      rc=lockProxy->pMethod->xClose((sqlite3_file *)lockProxy);
-+      if( rc ) return rc;
-+      sqlite3_free(lockProxy);
-+    }
-+    sqlite3_free(oldPath);
-+    pCtx->lockProxyPath = sqlite3DbStrDup(0, path);
-+  }
-+  
-+  return rc;
-+}
- 
--#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
--  { "CreateFileW",             (SYSCALL)CreateFileW,             0 },
--#else
--  { "CreateFileW",             (SYSCALL)0,                       0 },
-+/*
-+** pFile is a file that has been opened by a prior xOpen call.  dbPath
-+** is a string buffer at least MAXPATHLEN+1 characters in size.
-+**
-+** This routine find the filename associated with pFile and writes it
-+** int dbPath.
-+*/
-+static int proxyGetDbPathForUnixFile(unixFile *pFile, char *dbPath){
-+#if defined(__APPLE__)
-+  if( pFile->pMethod == &afpIoMethods ){
-+    /* 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);
-+  } else
- #endif
-+  if( pFile->pMethod == &dotlockIoMethods ){
-+    /* dot lock style uses the locking context to store the dot lock
-+    ** file path */
-+    int len = strlen((char *)pFile->lockingContext) - strlen(DOTLOCK_SUFFIX);
-+    memcpy(dbPath, (char *)pFile->lockingContext, len + 1);
-+  }else{
-+    /* all other styles use the locking context to store the db file path */
-+    assert( strlen((char*)pFile->lockingContext)<=MAXPATHLEN );
-+    strlcpy(dbPath, (char *)pFile->lockingContext, MAXPATHLEN);
-+  }
-+  return SQLITE_OK;
-+}
- 
--#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))
--  { "CreateFileMappingA",      (SYSCALL)CreateFileMappingA,      0 },
--#else
--  { "CreateFileMappingA",      (SYSCALL)0,                       0 },
--#endif
-+/*
-+** Takes an already filled in unix file and alters it so all file locking 
-+** will be performed on the local proxy lock file.  The following fields
-+** are preserved in the locking context so that they can be restored and 
-+** the unix structure properly cleaned up at close time:
-+**  ->lockingContext
-+**  ->pMethod
-+*/
-+static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
-+  proxyLockingContext *pCtx;
-+  char dbPath[MAXPATHLEN+1];       /* Name of the database file */
-+  char *lockPath=NULL;
-+  int rc = SQLITE_OK;
-+  
-+  if( pFile->eFileLock!=NO_LOCK ){
-+    return SQLITE_BUSY;
-+  }
-+  proxyGetDbPathForUnixFile(pFile, dbPath);
-+  if( !path || path[0]=='\0' || !strcmp(path, ":auto:") ){
-+    lockPath=NULL;
-+  }else{
-+    lockPath=(char *)path;
-+  }
-+  
-+  OSTRACE(("TRANSPROXY  %d for %s pid=%d\n", pFile->h,
-+           (lockPath ? lockPath : ":auto:"), getpid()));
- 
--#define osCreateFileMappingA ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
--        DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent)
-+  pCtx = sqlite3_malloc( sizeof(*pCtx) );
-+  if( pCtx==0 ){
-+    return SQLITE_NOMEM;
-+  }
-+  memset(pCtx, 0, sizeof(*pCtx));
- 
--#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
--        !defined(SQLITE_OMIT_WAL))
--  { "CreateFileMappingW",      (SYSCALL)CreateFileMappingW,      0 },
--#else
--  { "CreateFileMappingW",      (SYSCALL)0,                       0 },
--#endif
-+  rc = proxyCreateConchPathname(dbPath, &pCtx->conchFilePath);
-+  if( rc==SQLITE_OK ){
-+    rc = proxyCreateUnixFile(pCtx->conchFilePath, &pCtx->conchFile, 0);
-+    if( rc==SQLITE_CANTOPEN && ((pFile->openFlags&O_RDWR) == 0) ){
-+      /* if (a) the open flags are not O_RDWR, (b) the conch isn't there, and
-+      ** (c) the file system is read-only, then enable no-locking access.
-+      ** Ugh, since O_RDONLY==0x0000 we test for !O_RDWR since unixOpen asserts
-+      ** that openFlags will have only one of O_RDONLY or O_RDWR.
-+      */
-+      struct statfs fsInfo;
-+      struct stat conchInfo;
-+      int goLockless = 0;
- 
--#define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
--        DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent)
-+      if( osStat(pCtx->conchFilePath, &conchInfo) == -1 ) {
-+        int err = errno;
-+        if( (err==ENOENT) && (statfs(dbPath, &fsInfo) != -1) ){
-+          goLockless = (fsInfo.f_flags&MNT_RDONLY) == MNT_RDONLY;
-+        }
-+      }
-+      if( goLockless ){
-+        pCtx->conchHeld = -1; /* read only FS/ lockless */
-+        rc = SQLITE_OK;
-+      }
-+    }
-+  }  
-+  if( rc==SQLITE_OK && lockPath ){
-+    pCtx->lockProxyPath = sqlite3DbStrDup(0, lockPath);
-+  }
- 
--#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
--  { "CreateMutexW",            (SYSCALL)CreateMutexW,            0 },
--#else
--  { "CreateMutexW",            (SYSCALL)0,                       0 },
--#endif
-+  if( rc==SQLITE_OK ){
-+    pCtx->dbPath = sqlite3DbStrDup(0, dbPath);
-+    if( pCtx->dbPath==NULL ){
-+      rc = SQLITE_NOMEM;
-+    }
-+  }
-+  if( rc==SQLITE_OK ){
-+    /* all memory is allocated, proxys are created and assigned, 
-+    ** switch the locking context and pMethod then return.
-+    */
-+    pCtx->oldLockingContext = pFile->lockingContext;
-+    pFile->lockingContext = pCtx;
-+    pCtx->pOldMethod = pFile->pMethod;
-+    pFile->pMethod = &proxyIoMethods;
-+  }else{
-+    if( pCtx->conchFile ){ 
-+      pCtx->conchFile->pMethod->xClose((sqlite3_file *)pCtx->conchFile);
-+      sqlite3_free(pCtx->conchFile);
-+    }
-+    sqlite3DbFree(0, pCtx->lockProxyPath);
-+    sqlite3_free(pCtx->conchFilePath); 
-+    sqlite3_free(pCtx);
-+  }
-+  OSTRACE(("TRANSPROXY  %d %s\n", pFile->h,
-+           (rc==SQLITE_OK ? "ok" : "failed")));
-+  return rc;
-+}
- 
--#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
-+/*
-+** This routine handles sqlite3_file_control() calls that are specific
-+** to proxy locking.
-+*/
-+static int proxyFileControl(sqlite3_file *id, int op, void *pArg){
-+  switch( op ){
-+    case SQLITE_GET_LOCKPROXYFILE: {
-+      unixFile *pFile = (unixFile*)id;
-+      if( pFile->pMethod == &proxyIoMethods ){
-+        proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext;
-+        proxyTakeConch(pFile);
-+        if( pCtx->lockProxyPath ){
-+          *(const char **)pArg = pCtx->lockProxyPath;
-+        }else{
-+          *(const char **)pArg = ":auto: (not held)";
-+        }
-+      } else {
-+        *(const char **)pArg = NULL;
-+      }
-+      return SQLITE_OK;
-+    }
-+    case SQLITE_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 */
-+          rc = SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/;
-+        }else{
-+          /* turn off proxy locking - already off - NOOP */
-+          rc = SQLITE_OK;
-+        }
-+      }else{
-+        const char *proxyPath = (const char *)pArg;
-+        if( isProxyStyle ){
-+          proxyLockingContext *pCtx = 
-+            (proxyLockingContext*)pFile->lockingContext;
-+          if( !strcmp(pArg, ":auto:") 
-+           || (pCtx->lockProxyPath &&
-+               !strncmp(pCtx->lockProxyPath, proxyPath, MAXPATHLEN))
-+          ){
-+            rc = SQLITE_OK;
-+          }else{
-+            rc = switchLockProxyPath(pFile, proxyPath);
-+          }
-+        }else{
-+          /* turn on proxy file locking */
-+          rc = proxyTransformUnixFile(pFile, proxyPath);
-+        }
-+      }
-+      return rc;
-+    }
-+    default: {
-+      assert( 0 );  /* The call assures that only valid opcodes are sent */
-+    }
-+  }
-+  /*NOTREACHED*/
-+  return SQLITE_ERROR;
-+}
- 
--#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[9].pCurrent)
-+/*
-+** Within this division (the proxying locking implementation) the procedures
-+** above this point are all utilities.  The lock-related methods of the
-+** proxy-locking sqlite3_io_method object follow.
-+*/
- 
--#if defined(SQLITE_WIN32_HAS_WIDE)
--  { "DeleteFileW",             (SYSCALL)DeleteFileW,             0 },
--#else
--  { "DeleteFileW",             (SYSCALL)0,                       0 },
--#endif
- 
--#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[10].pCurrent)
-+/*
-+** 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, set *pResOut
-+** 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 proxyCheckReservedLock(sqlite3_file *id, int *pResOut) {
-+  unixFile *pFile = (unixFile*)id;
-+  int rc = proxyTakeConch(pFile);
-+  if( rc==SQLITE_OK ){
-+    proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
-+    if( pCtx->conchHeld>0 ){
-+      unixFile *proxy = pCtx->lockProxy;
-+      return proxy->pMethod->xCheckReservedLock((sqlite3_file*)proxy, pResOut);
-+    }else{ /* conchHeld < 0 is lockless */
-+      pResOut=0;
-+    }
-+  }
-+  return rc;
-+}
- 
--#if SQLITE_OS_WINCE
--  { "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 },
--#else
--  { "FileTimeToLocalFileTime", (SYSCALL)0,                       0 },
--#endif
-+/*
-+** Lock the file with the lock specified by parameter eFileLock - 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.  Use the sqlite3OsUnlock()
-+** routine to lower a locking level.
-+*/
-+static int proxyLock(sqlite3_file *id, int eFileLock) {
-+  unixFile *pFile = (unixFile*)id;
-+  int rc = proxyTakeConch(pFile);
-+  if( rc==SQLITE_OK ){
-+    proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
-+    if( pCtx->conchHeld>0 ){
-+      unixFile *proxy = pCtx->lockProxy;
-+      rc = proxy->pMethod->xLock((sqlite3_file*)proxy, eFileLock);
-+      pFile->eFileLock = proxy->eFileLock;
-+    }else{
-+      /* conchHeld < 0 is lockless */
-+    }
-+  }
-+  return rc;
-+}
- 
--#define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(CONST FILETIME*, \
--        LPFILETIME))aSyscall[11].pCurrent)
- 
--#if SQLITE_OS_WINCE
--  { "FileTimeToSystemTime",    (SYSCALL)FileTimeToSystemTime,    0 },
--#else
--  { "FileTimeToSystemTime",    (SYSCALL)0,                       0 },
--#endif
-+/*
-+** Lower the locking level on file descriptor pFile to eFileLock.  eFileLock
-+** 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.
-+*/
-+static int proxyUnlock(sqlite3_file *id, int eFileLock) {
-+  unixFile *pFile = (unixFile*)id;
-+  int rc = proxyTakeConch(pFile);
-+  if( rc==SQLITE_OK ){
-+    proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
-+    if( pCtx->conchHeld>0 ){
-+      unixFile *proxy = pCtx->lockProxy;
-+      rc = proxy->pMethod->xUnlock((sqlite3_file*)proxy, eFileLock);
-+      pFile->eFileLock = proxy->eFileLock;
-+    }else{
-+      /* conchHeld < 0 is lockless */
-+    }
-+  }
-+  return rc;
-+}
- 
--#define osFileTimeToSystemTime ((BOOL(WINAPI*)(CONST FILETIME*, \
--        LPSYSTEMTIME))aSyscall[12].pCurrent)
-+/*
-+** Close a file that uses proxy locks.
-+*/
-+static int proxyClose(sqlite3_file *id) {
-+  if( id ){
-+    unixFile *pFile = (unixFile*)id;
-+    proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
-+    unixFile *lockProxy = pCtx->lockProxy;
-+    unixFile *conchFile = pCtx->conchFile;
-+    int rc = SQLITE_OK;
-+    
-+    if( lockProxy ){
-+      rc = lockProxy->pMethod->xUnlock((sqlite3_file*)lockProxy, NO_LOCK);
-+      if( rc ) return rc;
-+      rc = lockProxy->pMethod->xClose((sqlite3_file*)lockProxy);
-+      if( rc ) return rc;
-+      sqlite3_free(lockProxy);
-+      pCtx->lockProxy = 0;
-+    }
-+    if( conchFile ){
-+      if( pCtx->conchHeld ){
-+        rc = proxyReleaseConch(pFile);
-+        if( rc ) return rc;
-+      }
-+      rc = conchFile->pMethod->xClose((sqlite3_file*)conchFile);
-+      if( rc ) return rc;
-+      sqlite3_free(conchFile);
-+    }
-+    sqlite3DbFree(0, pCtx->lockProxyPath);
-+    sqlite3_free(pCtx->conchFilePath);
-+    sqlite3DbFree(0, pCtx->dbPath);
-+    /* restore the original locking context and pMethod then close it */
-+    pFile->lockingContext = pCtx->oldLockingContext;
-+    pFile->pMethod = pCtx->pOldMethod;
-+    sqlite3_free(pCtx);
-+    return pFile->pMethod->xClose(id);
-+  }
-+  return SQLITE_OK;
-+}
- 
--  { "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
-+#endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
-+/*
-+** The proxy locking style is intended for use with AFP filesystems.
-+** And since AFP is only supported on MacOSX, the proxy locking is also
-+** restricted to MacOSX.
-+** 
-+**
-+******************* End of the proxy lock implementation **********************
-+******************************************************************************/
- 
--#define osFormatMessageA ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPSTR, \
--        DWORD,va_list*))aSyscall[14].pCurrent)
-+/*
-+** Initialize the operating system interface.
-+**
-+** This routine registers all VFS implementations for unix-like operating
-+** systems.  This routine, and the sqlite3_os_end() routine that follows,
-+** should be the only routines in this file that are visible from other
-+** files.
-+**
-+** This routine is called once during SQLite initialization and by a
-+** single thread.  The memory allocation and mutex subsystems have not
-+** necessarily been initialized when this routine is called, and so they
-+** should not be used.
-+*/
-+SQLITE_API int 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
-+  ** to the "finder" function.  (pAppData is a pointer to a pointer because
-+  ** silly C90 rules prohibit a void* from being cast to a function pointer
-+  ** and so we have to go through the intermediate pointer to avoid problems
-+  ** when compiling with -pedantic-errors on GCC.)
-+  **
-+  ** The FINDER parameter to this macro is the name of the pointer to the
-+  ** finder-function.  The finder-function returns a pointer to the
-+  ** sqlite_io_methods object that implements the desired locking
-+  ** behaviors.  See the division above that contains the IOMETHODS
-+  ** macro for addition information on finder-functions.
-+  **
-+  ** Most finders simply return a pointer to a fixed sqlite3_io_methods
-+  ** object.  But the "autolockIoFinder" available on MacOSX does a little
-+  ** more than that; it looks at the filesystem type that hosts the 
-+  ** database file and tries to choose an locking method appropriate for
-+  ** that filesystem time.
-+  */
-+  #define UNIXVFS(VFSNAME, FINDER) {                        \
-+    3,                    /* iVersion */                    \
-+    sizeof(unixFile),     /* szOsFile */                    \
-+    MAX_PATHNAME,         /* mxPathname */                  \
-+    0,                    /* pNext */                       \
-+    VFSNAME,              /* zName */                       \
-+    (void*)&FINDER,       /* pAppData */                    \
-+    unixOpen,             /* xOpen */                       \
-+    unixDelete,           /* xDelete */                     \
-+    unixAccess,           /* xAccess */                     \
-+    unixFullPathname,     /* xFullPathname */               \
-+    unixDlOpen,           /* xDlOpen */                     \
-+    unixDlError,          /* xDlError */                    \
-+    unixDlSym,            /* xDlSym */                      \
-+    unixDlClose,          /* xDlClose */                    \
-+    unixRandomness,       /* xRandomness */                 \
-+    unixSleep,            /* xSleep */                      \
-+    unixCurrentTime,      /* xCurrentTime */                \
-+    unixGetLastError,     /* xGetLastError */               \
-+    unixCurrentTimeInt64, /* xCurrentTimeInt64 */           \
-+    unixSetSystemCall,    /* xSetSystemCall */              \
-+    unixGetSystemCall,    /* xGetSystemCall */              \
-+    unixNextSystemCall,   /* xNextSystemCall */             \
-+  }
- 
--#if defined(SQLITE_WIN32_HAS_WIDE)
--  { "FormatMessageW",          (SYSCALL)FormatMessageW,          0 },
-+  /*
-+  ** All default VFSes for unix are contained in the following array.
-+  **
-+  ** Note that the sqlite3_vfs.pNext field of the VFS object is modified
-+  ** by the SQLite core when the VFS is registered.  So the following
-+  ** array cannot be const.
-+  */
-+  static sqlite3_vfs aVfs[] = {
-+#if SQLITE_ENABLE_LOCKING_STYLE && (OS_VXWORKS || defined(__APPLE__))
-+    UNIXVFS("unix",          autolockIoFinder ),
- #else
--  { "FormatMessageW",          (SYSCALL)0,                       0 },
-+    UNIXVFS("unix",          posixIoFinder ),
- #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 },
-+    UNIXVFS("unix-none",     nolockIoFinder ),
-+    UNIXVFS("unix-dotfile",  dotlockIoFinder ),
-+    UNIXVFS("unix-excl",     posixIoFinder ),
-+#if OS_VXWORKS
-+    UNIXVFS("unix-namedsem", semIoFinder ),
-+#endif
-+#if SQLITE_ENABLE_LOCKING_STYLE
-+    UNIXVFS("unix-posix",    posixIoFinder ),
-+#if !OS_VXWORKS
-+    UNIXVFS("unix-flock",    flockIoFinder ),
- #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 },
-+#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
-+    UNIXVFS("unix-afp",      afpIoFinder ),
-+    UNIXVFS("unix-nfs",      nfsIoFinder ),
-+    UNIXVFS("unix-proxy",    proxyIoFinder ),
- #endif
-+  };
-+  unsigned int i;          /* Loop counter */
- 
--#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
-+  /* Double-check that the aSyscall[] array has been constructed
-+  ** correctly.  See ticket [bb3a86e890c8e96ab] */
-+  assert( ArraySize(aSyscall)==24 );
- 
--#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[20].pCurrent)
-+  /* Register all VFSes defined in the aVfs[] array */
-+  for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
-+    sqlite3_vfs_register(&aVfs[i], i==0);
-+  }
-+  return SQLITE_OK; 
-+}
- 
--#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
--  { "GetFileAttributesW",      (SYSCALL)GetFileAttributesW,      0 },
--#else
--  { "GetFileAttributesW",      (SYSCALL)0,                       0 },
--#endif
-+/*
-+** Shutdown the operating system interface.
-+**
-+** Some operating systems might need to do some cleanup in this routine,
-+** to release dynamically allocated objects.  But not on unix.
-+** This routine is a no-op for unix.
-+*/
-+SQLITE_API int sqlite3_os_end(void){ 
-+  return SQLITE_OK; 
-+}
-+ 
-+#endif /* SQLITE_OS_UNIX */
- 
--#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[21].pCurrent)
-+/************** End of os_unix.c *********************************************/
-+/************** Begin file os_win.c ******************************************/
-+/*
-+** 2004 May 22
-+**
-+** 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 Windows.
-+*/
-+#if SQLITE_OS_WIN               /* This file is used for Windows only */
- 
--#if defined(SQLITE_WIN32_HAS_WIDE)
--  { "GetFileAttributesExW",    (SYSCALL)GetFileAttributesExW,    0 },
--#else
--  { "GetFileAttributesExW",    (SYSCALL)0,                       0 },
-+#ifdef __CYGWIN__
-+# include <sys/cygwin.h>
- #endif
- 
--#define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \
--        LPVOID))aSyscall[22].pCurrent)
-+/*
-+** Include code that is common to all os_*.c files
-+*/
-+/************** Include os_common.h in the middle of os_win.c ****************/
-+/************** Begin file os_common.h ***************************************/
-+/*
-+** 2004 May 22
-+**
-+** 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 macros and a little bit of code that is common to
-+** all of the platform-specific files (os_*.c) and is #included into those
-+** files.
-+**
-+** This file should be #included by the os_*.c files only.  It is not a
-+** general purpose header file.
-+*/
-+#ifndef _OS_COMMON_H_
-+#define _OS_COMMON_H_
- 
--#if !SQLITE_OS_WINRT
--  { "GetFileSize",             (SYSCALL)GetFileSize,             0 },
--#else
--  { "GetFileSize",             (SYSCALL)0,                       0 },
-+/*
-+** At least two bugs have slipped in because we changed the MEMORY_DEBUG
-+** macro to SQLITE_DEBUG and some older makefiles have not yet made the
-+** switch.  The following code should catch this problem at compile-time.
-+*/
-+#ifdef MEMORY_DEBUG
-+# error "The MEMORY_DEBUG macro is obsolete.  Use SQLITE_DEBUG instead."
- #endif
- 
--#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[23].pCurrent)
--
--#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
--  { "GetFullPathNameA",        (SYSCALL)GetFullPathNameA,        0 },
-+#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
--  { "GetFullPathNameA",        (SYSCALL)0,                       0 },
-+# define OSTRACE(X)
- #endif
- 
--#define osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \
--        LPSTR*))aSyscall[24].pCurrent)
-+/*
-+** Macros for performance tracing.  Normally turned off.  Only works
-+** on i486 hardware.
-+*/
-+#ifdef SQLITE_PERFORMANCE_TRACE
- 
--#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
--  { "GetFullPathNameW",        (SYSCALL)GetFullPathNameW,        0 },
--#else
--  { "GetFullPathNameW",        (SYSCALL)0,                       0 },
--#endif
-+/* 
-+** hwtime.h contains inline assembler code for implementing 
-+** high-performance timing routines.
-+*/
-+/************** Include hwtime.h in the middle of os_common.h ****************/
-+/************** Begin file hwtime.h ******************************************/
-+/*
-+** 2008 May 27
-+**
-+** 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 inline asm code for retrieving "high-performance"
-+** counters for x86 class CPUs.
-+*/
-+#ifndef _HWTIME_H_
-+#define _HWTIME_H_
- 
--#define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \
--        LPWSTR*))aSyscall[25].pCurrent)
-+/*
-+** The following routine only works on pentium-class (or newer) processors.
-+** It uses the RDTSC opcode to read the cycle count value out of the
-+** processor and returns that value.  This can be used for high-res
-+** profiling.
-+*/
-+#if (defined(__GNUC__) || defined(_MSC_VER)) && \
-+      (defined(i386) || defined(__i386__) || defined(_M_IX86))
- 
--  { "GetLastError",            (SYSCALL)GetLastError,            0 },
-+  #if defined(__GNUC__)
- 
--#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent)
-+  __inline__ sqlite_uint64 sqlite3Hwtime(void){
-+     unsigned int lo, hi;
-+     __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
-+     return (sqlite_uint64)hi << 32 | lo;
-+  }
- 
--#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
-+  #elif defined(_MSC_VER)
- 
--#define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \
--        LPCSTR))aSyscall[27].pCurrent)
-+  __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
-+     __asm {
-+        rdtsc
-+        ret       ; return value at EDX:EAX
-+     }
-+  }
- 
--#if !SQLITE_OS_WINRT
--  { "GetSystemInfo",           (SYSCALL)GetSystemInfo,           0 },
--#else
--  { "GetSystemInfo",           (SYSCALL)0,                       0 },
--#endif
-+  #endif
- 
--#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[28].pCurrent)
-+#elif (defined(__GNUC__) && defined(__x86_64__))
- 
--  { "GetSystemTime",           (SYSCALL)GetSystemTime,           0 },
-+  __inline__ sqlite_uint64 sqlite3Hwtime(void){
-+      unsigned long val;
-+      __asm__ __volatile__ ("rdtsc" : "=A" (val));
-+      return val;
-+  }
-+ 
-+#elif (defined(__GNUC__) && defined(__ppc__))
- 
--#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[29].pCurrent)
-+  __inline__ sqlite_uint64 sqlite3Hwtime(void){
-+      unsigned long long retval;
-+      unsigned long junk;
-+      __asm__ __volatile__ ("\n\
-+          1:      mftbu   %1\n\
-+                  mftb    %L0\n\
-+                  mftbu   %0\n\
-+                  cmpw    %0,%1\n\
-+                  bne     1b"
-+                  : "=r" (retval), "=r" (junk));
-+      return retval;
-+  }
- 
--#if !SQLITE_OS_WINCE
--  { "GetSystemTimeAsFileTime", (SYSCALL)GetSystemTimeAsFileTime, 0 },
- #else
--  { "GetSystemTimeAsFileTime", (SYSCALL)0,                       0 },
--#endif
- 
--#define osGetSystemTimeAsFileTime ((VOID(WINAPI*)( \
--        LPFILETIME))aSyscall[30].pCurrent)
-+  #error Need implementation of sqlite3Hwtime() for your platform.
-+
-+  /*
-+  ** To compile without implementing sqlite3Hwtime() for your platform,
-+  ** you can remove the above #error and use the following
-+  ** stub function.  You will lose timing support for many
-+  ** of the debugging and testing utilities, but it should at
-+  ** least compile and run.
-+  */
-+SQLITE_PRIVATE   sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
- 
--#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)
-+#endif /* !defined(_HWTIME_H_) */
- 
--#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
--  { "GetTempPathW",            (SYSCALL)GetTempPathW,            0 },
-+/************** End of hwtime.h **********************************************/
-+/************** Continuing where we left off in os_common.h ******************/
-+
-+static sqlite_uint64 g_start;
-+static sqlite_uint64 g_elapsed;
-+#define TIMER_START       g_start=sqlite3Hwtime()
-+#define TIMER_END         g_elapsed=sqlite3Hwtime()-g_start
-+#define TIMER_ELAPSED     g_elapsed
- #else
--  { "GetTempPathW",            (SYSCALL)0,                       0 },
-+#define TIMER_START
-+#define TIMER_END
-+#define TIMER_ELAPSED     ((sqlite_uint64)0)
- #endif
- 
--#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[32].pCurrent)
--
--#if !SQLITE_OS_WINRT
--  { "GetTickCount",            (SYSCALL)GetTickCount,            0 },
-+/*
-+** If we compile with the SQLITE_TEST macro set, then the following block
-+** of code will give us the ability to simulate a disk I/O error.  This
-+** is used for testing the I/O recovery logic.
-+*/
-+#ifdef SQLITE_TEST
-+SQLITE_API int sqlite3_io_error_hit = 0;            /* Total number of I/O Errors */
-+SQLITE_API int sqlite3_io_error_hardhit = 0;        /* Number of non-benign errors */
-+SQLITE_API int sqlite3_io_error_pending = 0;        /* Count down to first I/O error */
-+SQLITE_API int sqlite3_io_error_persist = 0;        /* True if I/O errors persist */
-+SQLITE_API int sqlite3_io_error_benign = 0;         /* True if errors are benign */
-+SQLITE_API int sqlite3_diskfull_pending = 0;
-+SQLITE_API int sqlite3_diskfull = 0;
-+#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X)
-+#define SimulateIOError(CODE)  \
-+  if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \
-+       || sqlite3_io_error_pending-- == 1 )  \
-+              { local_ioerr(); CODE; }
-+static void local_ioerr(){
-+  IOTRACE(("IOERR\n"));
-+  sqlite3_io_error_hit++;
-+  if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++;
-+}
-+#define SimulateDiskfullError(CODE) \
-+   if( sqlite3_diskfull_pending ){ \
-+     if( sqlite3_diskfull_pending == 1 ){ \
-+       local_ioerr(); \
-+       sqlite3_diskfull = 1; \
-+       sqlite3_io_error_hit = 1; \
-+       CODE; \
-+     }else{ \
-+       sqlite3_diskfull_pending--; \
-+     } \
-+   }
- #else
--  { "GetTickCount",            (SYSCALL)0,                       0 },
-+#define SimulateIOErrorBenign(X)
-+#define SimulateIOError(A)
-+#define SimulateDiskfullError(A)
- #endif
- 
--#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent)
--
--#if defined(SQLITE_WIN32_HAS_ANSI)
--  { "GetVersionExA",           (SYSCALL)GetVersionExA,           0 },
-+/*
-+** When testing, keep a count of the number of open files.
-+*/
-+#ifdef SQLITE_TEST
-+SQLITE_API int sqlite3_open_file_count = 0;
-+#define OpenCounter(X)  sqlite3_open_file_count+=(X)
- #else
--  { "GetVersionExA",           (SYSCALL)0,                       0 },
-+#define OpenCounter(X)
- #endif
- 
--#define osGetVersionExA ((BOOL(WINAPI*)( \
--        LPOSVERSIONINFOA))aSyscall[34].pCurrent)
--
--  { "HeapAlloc",               (SYSCALL)HeapAlloc,               0 },
-+#endif /* !defined(_OS_COMMON_H_) */
- 
--#define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \
--        SIZE_T))aSyscall[35].pCurrent)
-+/************** End of os_common.h *******************************************/
-+/************** Continuing where we left off in os_win.c *********************/
- 
--#if !SQLITE_OS_WINRT
--  { "HeapCreate",              (SYSCALL)HeapCreate,              0 },
--#else
--  { "HeapCreate",              (SYSCALL)0,                       0 },
-+/*
-+** Compiling and using WAL mode requires several APIs that are only
-+** available in Windows platforms based on the NT kernel.
-+*/
-+#if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL)
-+# error "WAL mode requires support from the Windows NT kernel, compile\
-+ with SQLITE_OMIT_WAL."
- #endif
- 
--#define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \
--        SIZE_T))aSyscall[36].pCurrent)
--
--#if !SQLITE_OS_WINRT
--  { "HeapDestroy",             (SYSCALL)HeapDestroy,             0 },
--#else
--  { "HeapDestroy",             (SYSCALL)0,                       0 },
-+/*
-+** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions
-+** based on the sub-platform)?
-+*/
-+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
-+#  define SQLITE_WIN32_HAS_ANSI
- #endif
- 
--#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[37].pCurrent)
--
--  { "HeapFree",                (SYSCALL)HeapFree,                0 },
-+/*
-+** Are most of the Win32 Unicode APIs available (i.e. with certain exceptions
-+** based on the sub-platform)?
-+*/
-+#if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT
-+#  define SQLITE_WIN32_HAS_WIDE
-+#endif
- 
--#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[38].pCurrent)
-+/*
-+** 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)?
-+*/
-+#if SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL)
-+/*
-+** Two of the file mapping APIs are different under WinRT.  Figure out which
-+** set we need.
-+*/
-+#if SQLITE_OS_WINRT
-+WINBASEAPI HANDLE WINAPI CreateFileMappingFromApp(HANDLE, \
-+        LPSECURITY_ATTRIBUTES, ULONG, ULONG64, LPCWSTR);
- 
--  { "HeapReAlloc",             (SYSCALL)HeapReAlloc,             0 },
-+WINBASEAPI LPVOID WINAPI MapViewOfFileFromApp(HANDLE, ULONG, ULONG64, SIZE_T);
-+#else
-+#if defined(SQLITE_WIN32_HAS_ANSI)
-+WINBASEAPI HANDLE WINAPI CreateFileMappingA(HANDLE, LPSECURITY_ATTRIBUTES, \
-+        DWORD, DWORD, DWORD, LPCSTR);
-+#endif /* defined(SQLITE_WIN32_HAS_ANSI) */
- 
--#define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \
--        SIZE_T))aSyscall[39].pCurrent)
-+#if defined(SQLITE_WIN32_HAS_WIDE)
-+WINBASEAPI HANDLE WINAPI CreateFileMappingW(HANDLE, LPSECURITY_ATTRIBUTES, \
-+        DWORD, DWORD, DWORD, LPCWSTR);
-+#endif /* defined(SQLITE_WIN32_HAS_WIDE) */
- 
--  { "HeapSize",                (SYSCALL)HeapSize,                0 },
-+WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T);
-+#endif /* SQLITE_OS_WINRT */
- 
--#define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \
--        LPCVOID))aSyscall[40].pCurrent)
-+/*
-+** This file mapping API is common to both Win32 and WinRT.
-+*/
-+WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID);
-+#endif /* SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL) */
- 
--#if !SQLITE_OS_WINRT
--  { "HeapValidate",            (SYSCALL)HeapValidate,            0 },
--#else
--  { "HeapValidate",            (SYSCALL)0,                       0 },
-+/*
-+** Macro to find the minimum of two numeric values.
-+*/
-+#ifndef MIN
-+# define MIN(x,y) ((x)<(y)?(x):(y))
- #endif
- 
--#define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \
--        LPCVOID))aSyscall[41].pCurrent)
--
--#if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
--  { "LoadLibraryA",            (SYSCALL)LoadLibraryA,            0 },
--#else
--  { "LoadLibraryA",            (SYSCALL)0,                       0 },
-+/*
-+** Some Microsoft compilers lack this definition.
-+*/
-+#ifndef INVALID_FILE_ATTRIBUTES
-+# define INVALID_FILE_ATTRIBUTES ((DWORD)-1) 
- #endif
- 
--#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[42].pCurrent)
--
--#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
--        !defined(SQLITE_OMIT_LOAD_EXTENSION)
--  { "LoadLibraryW",            (SYSCALL)LoadLibraryW,            0 },
--#else
--  { "LoadLibraryW",            (SYSCALL)0,                       0 },
-+#ifndef FILE_FLAG_MASK
-+# define FILE_FLAG_MASK          (0xFF3C0000)
- #endif
- 
--#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[43].pCurrent)
--
--#if !SQLITE_OS_WINRT
--  { "LocalFree",               (SYSCALL)LocalFree,               0 },
--#else
--  { "LocalFree",               (SYSCALL)0,                       0 },
-+#ifndef FILE_ATTRIBUTE_MASK
-+# define FILE_ATTRIBUTE_MASK     (0x0003FFF7)
- #endif
- 
--#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[44].pCurrent)
--
--#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
--  { "LockFile",                (SYSCALL)LockFile,                0 },
--#else
--  { "LockFile",                (SYSCALL)0,                       0 },
-+#ifndef SQLITE_OMIT_WAL
-+/* Forward references */
-+typedef struct winShm winShm;           /* A connection to shared-memory */
-+typedef struct winShmNode winShmNode;   /* A region of shared-memory */
- #endif
- 
--#ifndef osLockFile
--#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
--        DWORD))aSyscall[45].pCurrent)
-+/*
-+** WinCE lacks native support for file locking so we have to fake it
-+** with some code of our own.
-+*/
-+#if SQLITE_OS_WINCE
-+typedef struct winceLock {
-+  int nReaders;       /* Number of reader locks obtained */
-+  BOOL bPending;      /* Indicates a pending lock has been obtained */
-+  BOOL bReserved;     /* Indicates a reserved lock has been obtained */
-+  BOOL bExclusive;    /* Indicates an exclusive lock has been obtained */
-+} winceLock;
- #endif
- 
--#if !SQLITE_OS_WINCE
--  { "LockFileEx",              (SYSCALL)LockFileEx,              0 },
--#else
--  { "LockFileEx",              (SYSCALL)0,                       0 },
-+/*
-+** The winFile structure is a subclass of sqlite3_file* specific to the win32
-+** portability layer.
-+*/
-+typedef struct winFile winFile;
-+struct winFile {
-+  const sqlite3_io_methods *pMethod; /*** Must be first ***/
-+  sqlite3_vfs *pVfs;      /* The VFS used to open this file */
-+  HANDLE h;               /* Handle for accessing the file */
-+  u8 locktype;            /* Type of lock currently held on this file */
-+  short sharedLockByte;   /* Randomly chosen byte used as a shared lock */
-+  u8 ctrlFlags;           /* Flags.  See WINFILE_* below */
-+  DWORD lastErrno;        /* The Windows errno from the last I/O error */
-+#ifndef SQLITE_OMIT_WAL
-+  winShm *pShm;           /* Instance of shared memory on this file */
- #endif
--
--#ifndef osLockFileEx
--#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \
--        LPOVERLAPPED))aSyscall[46].pCurrent)
-+  const char *zPath;      /* Full pathname of this file */
-+  int szChunk;            /* Chunk size configured by FCNTL_CHUNK_SIZE */
-+#if SQLITE_OS_WINCE
-+  LPWSTR zDeleteOnClose;  /* Name of file to delete when closing */
-+  HANDLE hMutex;          /* Mutex used to control access to shared lock */  
-+  HANDLE hShared;         /* Shared memory segment used for locking */
-+  winceLock local;        /* Locks obtained by this instance of winFile */
-+  winceLock *shared;      /* Global shared lock memory for the file  */
- #endif
--
--#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL))
--  { "MapViewOfFile",           (SYSCALL)MapViewOfFile,           0 },
--#else
--  { "MapViewOfFile",           (SYSCALL)0,                       0 },
-+#if SQLITE_MAX_MMAP_SIZE>0
-+  int nFetchOut;                /* Number of outstanding xFetch references */
-+  HANDLE hMap;                  /* Handle for accessing memory mapping */
-+  void *pMapRegion;             /* Area memory mapped */
-+  sqlite3_int64 mmapSize;       /* Usable size of mapped region */
-+  sqlite3_int64 mmapSizeActual; /* Actual size of mapped region */
-+  sqlite3_int64 mmapSizeMax;    /* Configured FCNTL_MMAP_SIZE value */
- #endif
-+};
- 
--#define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
--        SIZE_T))aSyscall[47].pCurrent)
--
--  { "MultiByteToWideChar",     (SYSCALL)MultiByteToWideChar,     0 },
--
--#define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \
--        int))aSyscall[48].pCurrent)
--
--  { "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 },
--
--#define osQueryPerformanceCounter ((BOOL(WINAPI*)( \
--        LARGE_INTEGER*))aSyscall[49].pCurrent)
--
--  { "ReadFile",                (SYSCALL)ReadFile,                0 },
--
--#define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \
--        LPOVERLAPPED))aSyscall[50].pCurrent)
--
--  { "SetEndOfFile",            (SYSCALL)SetEndOfFile,            0 },
--
--#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[51].pCurrent)
-+/*
-+** Allowed values for winFile.ctrlFlags
-+*/
-+#define WINFILE_RDONLY          0x02   /* Connection is read only */
-+#define WINFILE_PERSIST_WAL     0x04   /* Persistent WAL mode */
-+#define WINFILE_PSOW            0x10   /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
- 
--#if !SQLITE_OS_WINRT
--  { "SetFilePointer",          (SYSCALL)SetFilePointer,          0 },
--#else
--  { "SetFilePointer",          (SYSCALL)0,                       0 },
-+/*
-+ * The size of the buffer used by sqlite3_win32_write_debug().
-+ */
-+#ifndef SQLITE_WIN32_DBG_BUF_SIZE
-+#  define SQLITE_WIN32_DBG_BUF_SIZE   ((int)(4096-sizeof(DWORD)))
- #endif
- 
--#define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \
--        DWORD))aSyscall[52].pCurrent)
--
--#if !SQLITE_OS_WINRT
--  { "Sleep",                   (SYSCALL)Sleep,                   0 },
--#else
--  { "Sleep",                   (SYSCALL)0,                       0 },
-+/*
-+ * The value used with sqlite3_win32_set_directory() to specify that
-+ * the data directory should be changed.
-+ */
-+#ifndef SQLITE_WIN32_DATA_DIRECTORY_TYPE
-+#  define SQLITE_WIN32_DATA_DIRECTORY_TYPE (1)
- #endif
- 
--#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[53].pCurrent)
--
--  { "SystemTimeToFileTime",    (SYSCALL)SystemTimeToFileTime,    0 },
-+/*
-+ * The value used with sqlite3_win32_set_directory() to specify that
-+ * the temporary directory should be changed.
-+ */
-+#ifndef SQLITE_WIN32_TEMP_DIRECTORY_TYPE
-+#  define SQLITE_WIN32_TEMP_DIRECTORY_TYPE (2)
-+#endif
- 
--#define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \
--        LPFILETIME))aSyscall[54].pCurrent)
-+/*
-+ * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the
-+ * various Win32 API heap functions instead of our own.
-+ */
-+#ifdef SQLITE_WIN32_MALLOC
- 
--#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
--  { "UnlockFile",              (SYSCALL)UnlockFile,              0 },
--#else
--  { "UnlockFile",              (SYSCALL)0,                       0 },
-+/*
-+ * If this is non-zero, an isolated heap will be created by the native Win32
-+ * allocator subsystem; otherwise, the default process heap will be used.  This
-+ * setting has no effect when compiling for WinRT.  By default, this is enabled
-+ * and an isolated heap will be created to store all allocated data.
-+ *
-+ ******************************************************************************
-+ * WARNING: It is important to note that when this setting is non-zero and the
-+ *          winMemShutdown function is called (e.g. by the sqlite3_shutdown
-+ *          function), all data that was allocated using the isolated heap will
-+ *          be freed immediately and any attempt to access any of that freed
-+ *          data will almost certainly result in an immediate access violation.
-+ ******************************************************************************
-+ */
-+#ifndef SQLITE_WIN32_HEAP_CREATE
-+#  define SQLITE_WIN32_HEAP_CREATE    (TRUE)
- #endif
- 
--#ifndef osUnlockFile
--#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
--        DWORD))aSyscall[55].pCurrent)
-+/*
-+ * The initial size of the Win32-specific heap.  This value may be zero.
-+ */
-+#ifndef SQLITE_WIN32_HEAP_INIT_SIZE
-+#  define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_DEFAULT_CACHE_SIZE) * \
-+                                       (SQLITE_DEFAULT_PAGE_SIZE) + 4194304)
- #endif
- 
--#if !SQLITE_OS_WINCE
--  { "UnlockFileEx",            (SYSCALL)UnlockFileEx,            0 },
--#else
--  { "UnlockFileEx",            (SYSCALL)0,                       0 },
-+/*
-+ * The maximum size of the Win32-specific heap.  This value may be zero.
-+ */
-+#ifndef SQLITE_WIN32_HEAP_MAX_SIZE
-+#  define SQLITE_WIN32_HEAP_MAX_SIZE  (0)
- #endif
- 
--#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
--        LPOVERLAPPED))aSyscall[56].pCurrent)
--
--#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL)
--  { "UnmapViewOfFile",         (SYSCALL)UnmapViewOfFile,         0 },
--#else
--  { "UnmapViewOfFile",         (SYSCALL)0,                       0 },
-+/*
-+ * The extra flags to use in calls to the Win32 heap APIs.  This value may be
-+ * zero for the default behavior.
-+ */
-+#ifndef SQLITE_WIN32_HEAP_FLAGS
-+#  define SQLITE_WIN32_HEAP_FLAGS     (0)
- #endif
- 
--#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[57].pCurrent)
--
--  { "WideCharToMultiByte",     (SYSCALL)WideCharToMultiByte,     0 },
--
--#define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \
--        LPCSTR,LPBOOL))aSyscall[58].pCurrent)
--
--  { "WriteFile",               (SYSCALL)WriteFile,               0 },
--
--#define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \
--        LPOVERLAPPED))aSyscall[59].pCurrent)
-+/*
-+** The winMemData structure stores information required by the Win32-specific
-+** sqlite3_mem_methods implementation.
-+*/
-+typedef struct winMemData winMemData;
-+struct winMemData {
-+#ifndef NDEBUG
-+  u32 magic;    /* Magic number to detect structure corruption. */
-+#endif
-+  HANDLE hHeap; /* The handle to our heap. */
-+  BOOL bOwned;  /* Do we own the heap (i.e. destroy it on shutdown)? */
-+};
- 
--#if SQLITE_OS_WINRT
--  { "CreateEventExW",          (SYSCALL)CreateEventExW,          0 },
--#else
--  { "CreateEventExW",          (SYSCALL)0,                       0 },
-+#ifndef NDEBUG
-+#define WINMEM_MAGIC     0x42b2830b
- #endif
- 
--#define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \
--        DWORD,DWORD))aSyscall[60].pCurrent)
-+static struct winMemData win_mem_data = {
-+#ifndef NDEBUG
-+  WINMEM_MAGIC,
-+#endif
-+  NULL, FALSE
-+};
- 
--#if !SQLITE_OS_WINRT
--  { "WaitForSingleObject",     (SYSCALL)WaitForSingleObject,     0 },
-+#ifndef NDEBUG
-+#define winMemAssertMagic() assert( win_mem_data.magic==WINMEM_MAGIC )
- #else
--  { "WaitForSingleObject",     (SYSCALL)0,                       0 },
-+#define winMemAssertMagic()
- #endif
- 
--#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
--        DWORD))aSyscall[61].pCurrent)
-+#define winMemGetHeap() win_mem_data.hHeap
- 
--#if SQLITE_OS_WINRT
--  { "WaitForSingleObjectEx",   (SYSCALL)WaitForSingleObjectEx,   0 },
--#else
--  { "WaitForSingleObjectEx",   (SYSCALL)0,                       0 },
--#endif
-+static void *winMemMalloc(int nBytes);
-+static void winMemFree(void *pPrior);
-+static void *winMemRealloc(void *pPrior, int nBytes);
-+static int winMemSize(void *p);
-+static int winMemRoundup(int n);
-+static int winMemInit(void *pAppData);
-+static void winMemShutdown(void *pAppData);
- 
--#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
--        BOOL))aSyscall[62].pCurrent)
-+SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetWin32(void);
-+#endif /* SQLITE_WIN32_MALLOC */
- 
--#if SQLITE_OS_WINRT
--  { "SetFilePointerEx",        (SYSCALL)SetFilePointerEx,        0 },
-+/*
-+** The following variable is (normally) set once and never changes
-+** thereafter.  It records whether the operating system is Win9x
-+** or WinNT.
-+**
-+** 0:   Operating system unknown.
-+** 1:   Operating system is Win9x.
-+** 2:   Operating system is WinNT.
-+**
-+** In order to facilitate testing on a WinNT system, the test fixture
-+** can manually set this value to 1 to emulate Win98 behavior.
-+*/
-+#ifdef SQLITE_TEST
-+SQLITE_API int sqlite3_os_type = 0;
- #else
--  { "SetFilePointerEx",        (SYSCALL)0,                       0 },
-+static int sqlite3_os_type = 0;
- #endif
- 
--#define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \
--        PLARGE_INTEGER,DWORD))aSyscall[63].pCurrent)
--
--#if SQLITE_OS_WINRT
--  { "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 },
--#else
--  { "GetFileInformationByHandleEx", (SYSCALL)0,                  0 },
-+#ifndef SYSCALL
-+#  define SYSCALL sqlite3_syscall_ptr
- #endif
- 
--#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
--        FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[64].pCurrent)
-+/*
-+** This function is not available on Windows CE or WinRT.
-+ */
- 
--#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
--  { "MapViewOfFileFromApp",    (SYSCALL)MapViewOfFileFromApp,    0 },
--#else
--  { "MapViewOfFileFromApp",    (SYSCALL)0,                       0 },
-+#if SQLITE_OS_WINCE || SQLITE_OS_WINRT
-+#  define osAreFileApisANSI()       1
- #endif
- 
--#define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \
--        SIZE_T))aSyscall[65].pCurrent)
--
--#if SQLITE_OS_WINRT
--  { "CreateFile2",             (SYSCALL)CreateFile2,             0 },
-+/*
-+** Many system calls are accessed through pointer-to-functions so that
-+** they may be overridden at runtime to facilitate fault injection during
-+** testing and sandboxing.  The following array holds the names and pointers
-+** to all overrideable system calls.
-+*/
-+static struct win_syscall {
-+  const char *zName;            /* Name of the system call */
-+  sqlite3_syscall_ptr pCurrent; /* Current value of the system call */
-+  sqlite3_syscall_ptr pDefault; /* Default value */
-+} aSyscall[] = {
-+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
-+  { "AreFileApisANSI",         (SYSCALL)AreFileApisANSI,         0 },
- #else
--  { "CreateFile2",             (SYSCALL)0,                       0 },
-+  { "AreFileApisANSI",         (SYSCALL)0,                       0 },
- #endif
- 
--#define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \
--        LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[66].pCurrent)
-+#ifndef osAreFileApisANSI
-+#define osAreFileApisANSI ((BOOL(WINAPI*)(VOID))aSyscall[0].pCurrent)
-+#endif
- 
--#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION)
--  { "LoadPackagedLibrary",     (SYSCALL)LoadPackagedLibrary,     0 },
-+#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE)
-+  { "CharLowerW",              (SYSCALL)CharLowerW,              0 },
- #else
--  { "LoadPackagedLibrary",     (SYSCALL)0,                       0 },
-+  { "CharLowerW",              (SYSCALL)0,                       0 },
- #endif
- 
--#define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \
--        DWORD))aSyscall[67].pCurrent)
-+#define osCharLowerW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[1].pCurrent)
- 
--#if SQLITE_OS_WINRT
--  { "GetTickCount64",          (SYSCALL)GetTickCount64,          0 },
-+#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE)
-+  { "CharUpperW",              (SYSCALL)CharUpperW,              0 },
- #else
--  { "GetTickCount64",          (SYSCALL)0,                       0 },
-+  { "CharUpperW",              (SYSCALL)0,                       0 },
- #endif
- 
--#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[68].pCurrent)
-+#define osCharUpperW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[2].pCurrent)
- 
--#if SQLITE_OS_WINRT
--  { "GetNativeSystemInfo",     (SYSCALL)GetNativeSystemInfo,     0 },
--#else
--  { "GetNativeSystemInfo",     (SYSCALL)0,                       0 },
--#endif
-+  { "CloseHandle",             (SYSCALL)CloseHandle,             0 },
- 
--#define osGetNativeSystemInfo ((VOID(WINAPI*)( \
--        LPSYSTEM_INFO))aSyscall[69].pCurrent)
-+#define osCloseHandle ((BOOL(WINAPI*)(HANDLE))aSyscall[3].pCurrent)
- 
- #if defined(SQLITE_WIN32_HAS_ANSI)
--  { "OutputDebugStringA",      (SYSCALL)OutputDebugStringA,      0 },
-+  { "CreateFileA",             (SYSCALL)CreateFileA,             0 },
- #else
--  { "OutputDebugStringA",      (SYSCALL)0,                       0 },
-+  { "CreateFileA",             (SYSCALL)0,                       0 },
- #endif
- 
--#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[70].pCurrent)
-+#define osCreateFileA ((HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD, \
-+        LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[4].pCurrent)
- 
--#if defined(SQLITE_WIN32_HAS_WIDE)
--  { "OutputDebugStringW",      (SYSCALL)OutputDebugStringW,      0 },
-+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
-+  { "CreateFileW",             (SYSCALL)CreateFileW,             0 },
- #else
--  { "OutputDebugStringW",      (SYSCALL)0,                       0 },
-+  { "CreateFileW",             (SYSCALL)0,                       0 },
- #endif
- 
--#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[71].pCurrent)
--
--  { "GetProcessHeap",          (SYSCALL)GetProcessHeap,          0 },
--
--#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[72].pCurrent)
-+#define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \
-+        LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)
- 
--#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
--  { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
-+#if (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \
-+        !defined(SQLITE_OMIT_WAL))
-+  { "CreateFileMappingA",      (SYSCALL)CreateFileMappingA,      0 },
- #else
--  { "CreateFileMappingFromApp", (SYSCALL)0,                      0 },
-+  { "CreateFileMappingA",      (SYSCALL)0,                       0 },
- #endif
- 
--#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
--        LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[73].pCurrent)
--
--}; /* End of the overrideable system calls */
--
--/*
--** 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;
--
--  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;
--}
--
--/*
--** 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;
--
--  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;
--}
--
--/*
--** 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;
--
--  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;
--}
--
--/*
--** This function outputs the specified (ANSI) string to the Win32 debugger
--** (if available).
--*/
-+#define osCreateFileMappingA ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
-+        DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent)
- 
--SQLITE_API void 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);
-+#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
-+        !defined(SQLITE_OMIT_WAL))
-+  { "CreateFileMappingW",      (SYSCALL)CreateFileMappingW,      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);
--  }
--#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;
-+  { "CreateFileMappingW",      (SYSCALL)0,                       0 },
- #endif
- 
--SQLITE_API void 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
--}
-+#define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
-+        DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent)
- 
--/*
--** 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 SQLITE_OS_WINCE || SQLITE_OS_WINRT
--# define isNT()  (1)
--#elif !defined(SQLITE_WIN32_HAS_WIDE)
--# define isNT()  (0)
-+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
-+  { "CreateMutexW",            (SYSCALL)CreateMutexW,            0 },
- #else
--  static int isNT(void){
--    if( sqlite3_os_type==0 ){
--      OSVERSIONINFOA sInfo;
--      sInfo.dwOSVersionInfoSize = sizeof(sInfo);
--      osGetVersionExA(&sInfo);
--      sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
--    }
--    return sqlite3_os_type==2;
--  }
-+  { "CreateMutexW",            (SYSCALL)0,                       0 },
- #endif
- 
--#ifdef SQLITE_WIN32_MALLOC
--/*
--** Allocate nBytes of memory.
--*/
--static void *winMemMalloc(int nBytes){
--  HANDLE hHeap;
--  void *p;
-+#define osCreateMutexW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,BOOL, \
-+        LPCWSTR))aSyscall[8].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 defined(SQLITE_WIN32_HAS_ANSI)
-+  { "DeleteFileA",             (SYSCALL)DeleteFileA,             0 },
-+#else
-+  { "DeleteFileA",             (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 (%d), heap=%p",
--                nBytes, osGetLastError(), (void*)hHeap);
--  }
--  return p;
--}
- 
--/*
--** Free memory.
--*/
--static void winMemFree(void *pPrior){
--  HANDLE hHeap;
-+#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[9].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_WIDE)
-+  { "DeleteFileW",             (SYSCALL)DeleteFileW,             0 },
-+#else
-+  { "DeleteFileW",             (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 (%d), 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 osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[10].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_WINCE
-+  { "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 },
-+#else
-+  { "FileTimeToLocalFileTime", (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 (%d), 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 osFileTimeToLocalFileTime ((BOOL(WINAPI*)(CONST FILETIME*, \
-+        LPFILETIME))aSyscall[11].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
-+  { "FileTimeToSystemTime",    (SYSCALL)FileTimeToSystemTime,    0 },
-+#else
-+  { "FileTimeToSystemTime",    (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 (%d), 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 osFileTimeToSystemTime ((BOOL(WINAPI*)(CONST FILETIME*, \
-+        LPSYSTEMTIME))aSyscall[12].pCurrent)
- 
--/*
--** Initialize this module.
--*/
--static int winMemInit(void *pAppData){
--  winMemData *pWinMemData = (winMemData *)pAppData;
-+  { "FlushFileBuffers",        (SYSCALL)FlushFileBuffers,        0 },
- 
--  if( !pWinMemData ) return SQLITE_ERROR;
--  assert( pWinMemData->magic==WINMEM_MAGIC );
-+#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[13].pCurrent)
- 
--#if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE
--  if( !pWinMemData->hHeap ){
--    pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS,
--                                      SQLITE_WIN32_HEAP_INIT_SIZE,
--                                      SQLITE_WIN32_HEAP_MAX_SIZE);
--    if( !pWinMemData->hHeap ){
--      sqlite3_log(SQLITE_NOMEM,
--          "failed to HeapCreate (%d), flags=%u, initSize=%u, maxSize=%u",
--          osGetLastError(), SQLITE_WIN32_HEAP_FLAGS,
--          SQLITE_WIN32_HEAP_INIT_SIZE, SQLITE_WIN32_HEAP_MAX_SIZE);
--      return SQLITE_NOMEM;
--    }
--    pWinMemData->bOwned = TRUE;
--    assert( pWinMemData->bOwned );
--  }
-+#if defined(SQLITE_WIN32_HAS_ANSI)
-+  { "FormatMessageA",          (SYSCALL)FormatMessageA,          0 },
- #else
--  pWinMemData->hHeap = osGetProcessHeap();
--  if( !pWinMemData->hHeap ){
--    sqlite3_log(SQLITE_NOMEM,
--        "failed to GetProcessHeap (%d)", osGetLastError());
--    return SQLITE_NOMEM;
--  }
--  pWinMemData->bOwned = FALSE;
--  assert( !pWinMemData->bOwned );
-+  { "FormatMessageA",          (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) );
-+
-+#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
--  return SQLITE_OK;
--}
- 
--/*
--** Deinitialize this module.
--*/
--static void winMemShutdown(void *pAppData){
--  winMemData *pWinMemData = (winMemData *)pAppData;
-+#define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \
-+        DWORD,va_list*))aSyscall[15].pCurrent)
- 
--  if( !pWinMemData ) return;
--  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) );
-+#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
-+  { "FreeLibrary",             (SYSCALL)FreeLibrary,             0 },
-+#else
-+  { "FreeLibrary",             (SYSCALL)0,                       0 },
- #endif
--    if( pWinMemData->bOwned ){
--      if( !osHeapDestroy(pWinMemData->hHeap) ){
--        sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%d), 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 osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent)
- 
--SQLITE_PRIVATE void sqlite3MemSetDefault(void){
--  sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetWin32());
--}
--#endif /* SQLITE_WIN32_MALLOC */
-+  { "GetCurrentProcessId",     (SYSCALL)GetCurrentProcessId,     0 },
- 
--/*
--** Convert a UTF-8 string to Microsoft Unicode (UTF-16?). 
--**
--** Space to hold the returned string is obtained from malloc.
--*/
--static LPWSTR utf8ToUnicode(const char *zFilename){
--  int nChar;
--  LPWSTR zWideFilename;
-+#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[17].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;
--}
-+#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
-+  { "GetDiskFreeSpaceA",       (SYSCALL)GetDiskFreeSpaceA,       0 },
-+#else
-+  { "GetDiskFreeSpaceA",       (SYSCALL)0,                       0 },
-+#endif
- 
--/*
--** Convert Microsoft Unicode to UTF-8.  Space to hold the returned string is
--** obtained from sqlite3_malloc().
--*/
--static char *unicodeToUtf8(LPCWSTR zWideFilename){
--  int nByte;
--  char *zFilename;
-+#define osGetDiskFreeSpaceA ((BOOL(WINAPI*)(LPCSTR,LPDWORD,LPDWORD,LPDWORD, \
-+        LPDWORD))aSyscall[18].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 && defined(SQLITE_WIN32_HAS_WIDE)
-+  { "GetDiskFreeSpaceW",       (SYSCALL)GetDiskFreeSpaceW,       0 },
-+#else
-+  { "GetDiskFreeSpaceW",       (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 mbcsToUnicode(const char *zFilename){
--  int nByte;
--  LPWSTR zMbcsFilename;
--  int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
-+#define osGetDiskFreeSpaceW ((BOOL(WINAPI*)(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, \
-+        LPDWORD))aSyscall[19].pCurrent)
- 
--  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 defined(SQLITE_WIN32_HAS_ANSI)
-+  { "GetFileAttributesA",      (SYSCALL)GetFileAttributesA,      0 },
-+#else
-+  { "GetFileAttributesA",      (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 *unicodeToMbcs(LPCWSTR zWideFilename){
--  int nByte;
--  char *zFilename;
--  int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
-+#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[20].pCurrent)
- 
--  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;
--}
-+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
-+  { "GetFileAttributesW",      (SYSCALL)GetFileAttributesW,      0 },
-+#else
-+  { "GetFileAttributesW",      (SYSCALL)0,                       0 },
-+#endif
- 
--/*
--** 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){
--  char *zFilenameUtf8;
--  LPWSTR zTmpWide;
-+#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[21].pCurrent)
- 
--  zTmpWide = mbcsToUnicode(zFilename);
--  if( zTmpWide==0 ){
--    return 0;
--  }
--  zFilenameUtf8 = unicodeToUtf8(zTmpWide);
--  sqlite3_free(zTmpWide);
--  return zFilenameUtf8;
--}
-+#if defined(SQLITE_WIN32_HAS_WIDE)
-+  { "GetFileAttributesExW",    (SYSCALL)GetFileAttributesExW,    0 },
-+#else
-+  { "GetFileAttributesExW",    (SYSCALL)0,                       0 },
-+#endif
- 
--/*
--** 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){
--  char *zFilenameMbcs;
--  LPWSTR zTmpWide;
-+#define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \
-+        LPVOID))aSyscall[22].pCurrent)
- 
--  zTmpWide = utf8ToUnicode(zFilename);
--  if( zTmpWide==0 ){
--    return 0;
--  }
--  zFilenameMbcs = unicodeToMbcs(zTmpWide);
--  sqlite3_free(zTmpWide);
--  return zFilenameMbcs;
--}
-+#if !SQLITE_OS_WINRT
-+  { "GetFileSize",             (SYSCALL)GetFileSize,             0 },
-+#else
-+  { "GetFileSize",             (SYSCALL)0,                       0 },
-+#endif
- 
--/*
--** 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 sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
--  char **ppDirectory = 0;
--#ifndef SQLITE_OMIT_AUTOINIT
--  int rc = sqlite3_initialize();
--  if( rc ) return rc;
-+#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
--  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 = unicodeToUtf8(zValue);
--      if ( zValueUtf8==0 ){
--        return SQLITE_NOMEM;
--      }
--    }
--    sqlite3_free(*ppDirectory);
--    *ppDirectory = zValueUtf8;
--    return SQLITE_OK;
--  }
--  return SQLITE_ERROR;
--}
- 
--/*
--** The return value of getLastErrorMsg
--** is zero if the error message fits in the buffer, or non-zero
--** otherwise (if the message was truncated).
--*/
--static int getLastErrorMsg(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 osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \
-+        LPSTR*))aSyscall[24].pCurrent)
- 
--  if( isNT() ){
--#if SQLITE_OS_WINRT
--    WCHAR zTempWide[MAX_PATH+1]; /* NOTE: Somewhat arbitrary. */
--    dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
--                             FORMAT_MESSAGE_IGNORE_INSERTS,
--                             NULL,
--                             lastErrno,
--                             0,
--                             zTempWide,
--                             MAX_PATH,
--                             0);
-+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
-+  { "GetFullPathNameW",        (SYSCALL)GetFullPathNameW,        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);
-+  { "GetFullPathNameW",        (SYSCALL)0,                       0 },
- #endif
--    if( dwLen > 0 ){
--      /* allocate a buffer and convert to UTF8 */
--      sqlite3BeginBenignMalloc();
--      zOut = unicodeToUtf8(zTempWide);
--      sqlite3EndBenignMalloc();
-+
-+#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
--      /* free the system buffer allocated by FormatMessage */
--      osLocalFree(zTempWide);
-+  { "GetSystemInfo",           (SYSCALL)GetSystemInfo,           0 },
-+#else
-+  { "GetSystemInfo",           (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 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
--  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 osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[31].pCurrent)
- 
--  zMsg[0] = 0;
--  getLastErrorMsg(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 && defined(SQLITE_WIN32_HAS_WIDE)
-+  { "GetTempPathW",            (SYSCALL)GetTempPathW,            0 },
-+#else
-+  { "GetTempPathW",            (SYSCALL)0,                       0 },
-+#endif
- 
--  return errcode;
--}
-+#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[32].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
-+  { "GetTickCount",            (SYSCALL)GetTickCount,            0 },
-+#else
-+  { "GetTickCount",            (SYSCALL)0,                       0 },
- #endif
--#ifndef SQLITE_WIN32_IOERR_RETRY_DELAY
--# define SQLITE_WIN32_IOERR_RETRY_DELAY 25
-+
-+#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent)
-+
-+#if defined(SQLITE_WIN32_HAS_ANSI)
-+  { "GetVersionExA",           (SYSCALL)GetVersionExA,           0 },
-+#else
-+  { "GetVersionExA",           (SYSCALL)0,                       0 },
- #endif
--static int win32IoerrRetry = SQLITE_WIN32_IOERR_RETRY;
--static int win32IoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY;
- 
--/*
--** 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 retryIoerr(int *pnRetry, DWORD *pError){
--  DWORD e = osGetLastError();
--  if( *pnRetry>=win32IoerrRetry ){
--    if( pError ){
--      *pError = e;
--    }
--    return 0;
--  }
--  if( e==ERROR_ACCESS_DENIED ||
--      e==ERROR_LOCK_VIOLATION ||
--      e==ERROR_SHARING_VIOLATION ){
--    sqlite3_win32_sleep(win32IoerrRetryDelay*(1+*pnRetry));
--    ++*pnRetry;
--    return 1;
--  }
--  if( pError ){
--    *pError = e;
--  }
--  return 0;
--}
-+#define osGetVersionExA ((BOOL(WINAPI*)( \
-+        LPOSVERSIONINFOA))aSyscall[34].pCurrent)
- 
--/*
--** Log a I/O error retry episode.
--*/
--static void logIoerr(int nRetry){
--  if( nRetry ){
--    sqlite3_log(SQLITE_IOERR, 
--      "delayed %dms for lock/sharing conflict",
--      win32IoerrRetryDelay*nRetry*(nRetry+1)/2
--    );
--  }
--}
-+  { "HeapAlloc",               (SYSCALL)HeapAlloc,               0 },
- 
--#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;
--}
-+#define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \
-+        SIZE_T))aSyscall[35].pCurrent)
-+
-+#if !SQLITE_OS_WINRT
-+  { "HeapCreate",              (SYSCALL)HeapCreate,              0 },
-+#else
-+  { "HeapCreate",              (SYSCALL)0,                       0 },
- #endif
- 
--#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)]
-+#define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \
-+        SIZE_T))aSyscall[36].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)
-+#if !SQLITE_OS_WINRT
-+  { "HeapDestroy",             (SYSCALL)HeapDestroy,             0 },
-+#else
-+  { "HeapDestroy",             (SYSCALL)0,                       0 },
-+#endif
- 
--/*
--** 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 osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[37].pCurrent)
- 
--  zName = utf8ToUnicode(zFilename);
--  if( zName==0 ){
--    /* out of memory */
--    return SQLITE_IOERR_NOMEM;
--  }
-+  { "HeapFree",                (SYSCALL)HeapFree,                0 },
- 
--  /* Initialize the local lockdata */
--  memset(&pFile->local, 0, sizeof(pFile->local));
-+#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[38].pCurrent)
- 
--  /* Replace the backslashes from the filename and lowercase it
--  ** to derive a mutex name. */
--  zTok = osCharLowerW(zName);
--  for (;*zTok;zTok++){
--    if (*zTok == '\\') *zTok = '_';
--  }
-+  { "HeapReAlloc",             (SYSCALL)HeapReAlloc,             0 },
- 
--  /* Create/open the named mutex */
--  pFile->hMutex = osCreateMutexW(NULL, FALSE, zName);
--  if (!pFile->hMutex){
--    pFile->lastErrno = osGetLastError();
--    winLogError(SQLITE_IOERR, pFile->lastErrno,
--                "winceCreateLock1", zFilename);
--    sqlite3_free(zName);
--    return SQLITE_IOERR;
--  }
-+#define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \
-+        SIZE_T))aSyscall[39].pCurrent)
- 
--  /* Acquire the mutex before continuing */
--  winceMutexAcquire(pFile->hMutex);
--  
--  /* 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);  
-+  { "HeapSize",                (SYSCALL)HeapSize,                0 },
- 
--  /* 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 osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \
-+        LPCVOID))aSyscall[40].pCurrent)
- 
--  sqlite3_free(zName);
-+#if !SQLITE_OS_WINRT
-+  { "HeapValidate",            (SYSCALL)HeapValidate,            0 },
-+#else
-+  { "HeapValidate",            (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 osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \
-+        LPCVOID))aSyscall[41].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;
--  }
--  
--  /* Initialize the shared memory if we're supposed to */
--  if( bInit ){
--    memset(pFile->shared, 0, sizeof(winceLock));
--  }
-+#if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
-+  { "LoadLibraryA",            (SYSCALL)LoadLibraryA,            0 },
-+#else
-+  { "LoadLibraryA",            (SYSCALL)0,                       0 },
-+#endif
- 
--  winceMutexRelease(pFile->hMutex);
--  return SQLITE_OK;
--}
-+#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[42].pCurrent)
- 
--/*
--** Destroy the part of winFile that deals with wince locks
--*/
--static void winceDestroyLock(winFile *pFile){
--  if (pFile->hMutex){
--    /* Acquire the mutex */
--    winceMutexAcquire(pFile->hMutex);
-+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
-+        !defined(SQLITE_OMIT_LOAD_EXTENSION)
-+  { "LoadLibraryW",            (SYSCALL)LoadLibraryW,            0 },
-+#else
-+  { "LoadLibraryW",            (SYSCALL)0,                       0 },
-+#endif
- 
--    /* 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;
--    }
--    if (pFile->local.bExclusive){
--      pFile->shared->bExclusive = FALSE;
--    }
-+#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[43].pCurrent)
- 
--    /* De-reference and close our copy of the shared memory handle */
--    osUnmapViewOfFile(pFile->shared);
--    osCloseHandle(pFile->hShared);
-+#if !SQLITE_OS_WINRT
-+  { "LocalFree",               (SYSCALL)LocalFree,               0 },
-+#else
-+  { "LocalFree",               (SYSCALL)0,                       0 },
-+#endif
- 
--    /* Done with the mutex */
--    winceMutexRelease(pFile->hMutex);    
--    osCloseHandle(pFile->hMutex);
--    pFile->hMutex = NULL;
--  }
--}
-+#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[44].pCurrent)
- 
--/* 
--** An implementation of the LockFile() API of Windows for CE
--*/
--static BOOL winceLockFile(
--  LPHANDLE phFile,
--  DWORD dwFileOffsetLow,
--  DWORD dwFileOffsetHigh,
--  DWORD nNumberOfBytesToLockLow,
--  DWORD nNumberOfBytesToLockHigh
--){
--  winFile *pFile = HANDLE_TO_WINFILE(phFile);
--  BOOL bReturn = FALSE;
-+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
-+  { "LockFile",                (SYSCALL)LockFile,                0 },
-+#else
-+  { "LockFile",                (SYSCALL)0,                       0 },
-+#endif
- 
--  UNUSED_PARAMETER(dwFileOffsetHigh);
--  UNUSED_PARAMETER(nNumberOfBytesToLockHigh);
-+#ifndef osLockFile
-+#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
-+        DWORD))aSyscall[45].pCurrent)
-+#endif
- 
--  if (!pFile->hMutex) return TRUE;
--  winceMutexAcquire(pFile->hMutex);
-+#if !SQLITE_OS_WINCE
-+  { "LockFileEx",              (SYSCALL)LockFileEx,              0 },
-+#else
-+  { "LockFileEx",              (SYSCALL)0,                       0 },
-+#endif
- 
--  /* 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;
--    }
--  }
-+#ifndef osLockFileEx
-+#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \
-+        LPOVERLAPPED))aSyscall[46].pCurrent)
-+#endif
- 
--  /* 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 SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL))
-+  { "MapViewOfFile",           (SYSCALL)MapViewOfFile,           0 },
-+#else
-+  { "MapViewOfFile",           (SYSCALL)0,                       0 },
-+#endif
- 
--  /* 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;
--    }
--  }
-+#define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
-+        SIZE_T))aSyscall[47].pCurrent)
- 
--  /* 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;
--    }
--  }
-+  { "MultiByteToWideChar",     (SYSCALL)MultiByteToWideChar,     0 },
- 
--  winceMutexRelease(pFile->hMutex);
--  return bReturn;
--}
-+#define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \
-+        int))aSyscall[48].pCurrent)
- 
--/*
--** An implementation of the UnlockFile API of Windows for CE
--*/
--static BOOL winceUnlockFile(
--  LPHANDLE phFile,
--  DWORD dwFileOffsetLow,
--  DWORD dwFileOffsetHigh,
--  DWORD nNumberOfBytesToUnlockLow,
--  DWORD nNumberOfBytesToUnlockHigh
--){
--  winFile *pFile = HANDLE_TO_WINFILE(phFile);
--  BOOL bReturn = FALSE;
-+  { "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 },
- 
--  UNUSED_PARAMETER(dwFileOffsetHigh);
--  UNUSED_PARAMETER(nNumberOfBytesToUnlockHigh);
-+#define osQueryPerformanceCounter ((BOOL(WINAPI*)( \
-+        LARGE_INTEGER*))aSyscall[49].pCurrent)
- 
--  if (!pFile->hMutex) return TRUE;
--  winceMutexAcquire(pFile->hMutex);
-+  { "ReadFile",                (SYSCALL)ReadFile,                0 },
- 
--  /* 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;
--    }
-+#define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \
-+        LPOVERLAPPED))aSyscall[50].pCurrent)
- 
--    /* 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;
--    }
--  }
-+  { "SetEndOfFile",            (SYSCALL)SetEndOfFile,            0 },
- 
--  /* 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;
--    }
--  }
--  /* 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;
--    }
--  }
-+#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[51].pCurrent)
- 
--  winceMutexRelease(pFile->hMutex);
--  return bReturn;
--}
--/*
--** End of the special code for wince
--*****************************************************************************/
--#endif /* SQLITE_OS_WINCE */
-+#if !SQLITE_OS_WINRT
-+  { "SetFilePointer",          (SYSCALL)SetFilePointer,          0 },
-+#else
-+  { "SetFilePointer",          (SYSCALL)0,                       0 },
-+#endif
- 
--/*
--** 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);
-+#define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \
-+        DWORD))aSyscall[52].pCurrent)
-+
-+#if !SQLITE_OS_WINRT
-+  { "Sleep",                   (SYSCALL)Sleep,                   0 },
-+#else
-+  { "Sleep",                   (SYSCALL)0,                       0 },
-+#endif
-+
-+#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[53].pCurrent)
-+
-+  { "SystemTimeToFileTime",    (SYSCALL)SystemTimeToFileTime,    0 },
-+
-+#define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \
-+        LPFILETIME))aSyscall[54].pCurrent)
-+
-+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
-+  { "UnlockFile",              (SYSCALL)UnlockFile,              0 },
- #else
--  if( isNT() ){
--    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);
--  }
-+  { "UnlockFile",              (SYSCALL)0,                       0 },
- #endif
--}
- 
--/*
--** 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);
-+#ifndef osUnlockFile
-+#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
-+        DWORD))aSyscall[55].pCurrent)
-+#endif
-+
-+#if !SQLITE_OS_WINCE
-+  { "UnlockFileEx",            (SYSCALL)UnlockFileEx,            0 },
- #else
--  if( isNT() ){
--    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);
--  }
-+  { "UnlockFileEx",            (SYSCALL)0,                       0 },
- #endif
--}
- 
--/*****************************************************************************
--** The next group of routines implement the I/O methods specified
--** by the sqlite3_io_methods object.
--******************************************************************************/
-+#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
-+        LPOVERLAPPED))aSyscall[56].pCurrent)
- 
--/*
--** Some Microsoft compilers lack this definition.
--*/
--#ifndef INVALID_SET_FILE_POINTER
--# define INVALID_SET_FILE_POINTER ((DWORD)-1)
-+#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL)
-+  { "UnmapViewOfFile",         (SYSCALL)UnmapViewOfFile,         0 },
-+#else
-+  { "UnmapViewOfFile",         (SYSCALL)0,                       0 },
- #endif
- 
--/*
--** 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 int seekWinFile(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() */
-+#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[57].pCurrent)
- 
--  OSTRACE(("SEEK file=%p, offset=%lld\n", pFile->h, iOffset));
-+  { "WideCharToMultiByte",     (SYSCALL)WideCharToMultiByte,     0 },
- 
--  upperBits = (LONG)((iOffset>>32) & 0x7fffffff);
--  lowerBits = (LONG)(iOffset & 0xffffffff);
-+#define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \
-+        LPCSTR,LPBOOL))aSyscall[58].pCurrent)
- 
--  /* 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);
-+  { "WriteFile",               (SYSCALL)WriteFile,               0 },
- 
--  if( (dwRet==INVALID_SET_FILE_POINTER
--      && ((lastErrno = osGetLastError())!=NO_ERROR)) ){
--    pFile->lastErrno = lastErrno;
--    winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
--             "seekWinFile", pFile->zPath);
--    OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
--    return 1;
--  }
-+#define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \
-+        LPOVERLAPPED))aSyscall[59].pCurrent)
- 
--  OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h));
--  return 0;
-+#if SQLITE_OS_WINRT
-+  { "CreateEventExW",          (SYSCALL)CreateEventExW,          0 },
- #else
--  /*
--  ** Same as above, except that this implementation works for WinRT.
--  */
-+  { "CreateEventExW",          (SYSCALL)0,                       0 },
-+#endif
- 
--  LARGE_INTEGER x;                /* The new offset */
--  BOOL bRet;                      /* Value returned by SetFilePointerEx() */
-+#define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \
-+        DWORD,DWORD))aSyscall[60].pCurrent)
- 
--  x.QuadPart = iOffset;
--  bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN);
-+#if !SQLITE_OS_WINRT
-+  { "WaitForSingleObject",     (SYSCALL)WaitForSingleObject,     0 },
-+#else
-+  { "WaitForSingleObject",     (SYSCALL)0,                       0 },
-+#endif
- 
--  if(!bRet){
--    pFile->lastErrno = osGetLastError();
--    winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
--             "seekWinFile", pFile->zPath);
--    OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
--    return 1;
--  }
-+#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
-+        DWORD))aSyscall[61].pCurrent)
- 
--  OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h));
--  return 0;
-+#if SQLITE_OS_WINRT
-+  { "WaitForSingleObjectEx",   (SYSCALL)WaitForSingleObjectEx,   0 },
-+#else
-+  { "WaitForSingleObjectEx",   (SYSCALL)0,                       0 },
- #endif
--}
- 
--#if SQLITE_MAX_MMAP_SIZE>0
--/* Forward references to VFS methods */
--static int winUnmapfile(winFile*);
-+#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
-+        BOOL))aSyscall[62].pCurrent)
-+
-+#if SQLITE_OS_WINRT
-+  { "SetFilePointerEx",        (SYSCALL)SetFilePointerEx,        0 },
-+#else
-+  { "SetFilePointerEx",        (SYSCALL)0,                       0 },
- #endif
- 
--/*
--** 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.
--*/
--#define MX_CLOSE_ATTEMPT 3
--static int winClose(sqlite3_file *id){
--  int rc, cnt = 0;
--  winFile *pFile = (winFile*)id;
-+#define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \
-+        PLARGE_INTEGER,DWORD))aSyscall[63].pCurrent)
- 
--  assert( id!=0 );
--#ifndef SQLITE_OMIT_WAL
--  assert( pFile->pShm==0 );
-+#if SQLITE_OS_WINRT
-+  { "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 },
-+#else
-+  { "GetFileInformationByHandleEx", (SYSCALL)0,                  0 },
- #endif
--  assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE );
--  OSTRACE(("CLOSE file=%p\n", pFile->h));
- 
--#if SQLITE_MAX_MMAP_SIZE>0
--  rc = winUnmapfile(pFile);
--  if( rc!=SQLITE_OK ) return rc;
--#endif
-+#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
-+        FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[64].pCurrent)
- 
--  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);
--  }
-+#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
-+  { "MapViewOfFileFromApp",    (SYSCALL)MapViewOfFileFromApp,    0 },
-+#else
-+  { "MapViewOfFileFromApp",    (SYSCALL)0,                       0 },
- #endif
--  if( rc ){
--    pFile->h = NULL;
--  }
--  OpenCounter(-1);
--  OSTRACE(("CLOSE file=%p, rc=%s\n", 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.
--*/
--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
--  OVERLAPPED overlapped;          /* The offset for ReadFile. */
-+#define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \
-+        SIZE_T))aSyscall[65].pCurrent)
-+
-+#if SQLITE_OS_WINRT
-+  { "CreateFile2",             (SYSCALL)CreateFile2,             0 },
-+#else
-+  { "CreateFile2",             (SYSCALL)0,                       0 },
- #endif
--  winFile *pFile = (winFile*)id;  /* file handle */
--  DWORD nRead;                    /* Number of bytes actually read from file */
--  int nRetry = 0;                 /* Number of retrys */
- 
--  assert( id!=0 );
--  assert( amt>0 );
--  assert( offset>=0 );
--  SimulateIOError(return SQLITE_IOERR_READ);
--  OSTRACE(("READ file=%p, buffer=%p, amount=%d, offset=%lld, lock=%d\n",
--           pFile->h, pBuf, amt, offset, pFile->locktype));
-+#define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \
-+        LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[66].pCurrent)
- 
--#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 file=%p, rc=SQLITE_OK\n", 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;
--    }
--  }
-+#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION)
-+  { "LoadPackagedLibrary",     (SYSCALL)LoadPackagedLibrary,     0 },
-+#else
-+  { "LoadPackagedLibrary",     (SYSCALL)0,                       0 },
- #endif
- 
--#if SQLITE_OS_WINCE
--  if( seekWinFile(pFile, offset) ){
--    OSTRACE(("READ file=%p, rc=SQLITE_FULL\n", pFile->h));
--    return SQLITE_FULL;
--  }
--  while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
-+#define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \
-+        DWORD))aSyscall[67].pCurrent)
-+
-+#if SQLITE_OS_WINRT
-+  { "GetTickCount64",          (SYSCALL)GetTickCount64,          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 ){
-+  { "GetTickCount64",          (SYSCALL)0,                       0 },
- #endif
--    DWORD lastErrno;
--    if( retryIoerr(&nRetry, &lastErrno) ) continue;
--    pFile->lastErrno = lastErrno;
--    OSTRACE(("READ file=%p, rc=SQLITE_IOERR_READ\n", pFile->h));
--    return winLogError(SQLITE_IOERR_READ, pFile->lastErrno,
--             "winRead", pFile->zPath);
--  }
--  logIoerr(nRetry);
--  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));
--    return SQLITE_IOERR_SHORT_READ;
--  }
--
--  OSTRACE(("READ file=%p, rc=SQLITE_OK\n", pFile->h));
--  return SQLITE_OK;
--}
- 
--/*
--** Write data from a buffer into a file.  Return SQLITE_OK on success
--** or some other error code on failure.
--*/
--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 */
-+#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[68].pCurrent)
- 
--  assert( amt>0 );
--  assert( pFile );
--  SimulateIOError(return SQLITE_IOERR_WRITE);
--  SimulateDiskfullError(return SQLITE_FULL);
-+#if SQLITE_OS_WINRT
-+  { "GetNativeSystemInfo",     (SYSCALL)GetNativeSystemInfo,     0 },
-+#else
-+  { "GetNativeSystemInfo",     (SYSCALL)0,                       0 },
-+#endif
- 
--  OSTRACE(("WRITE file=%p, buffer=%p, amount=%d, offset=%lld, lock=%d\n",
--           pFile->h, pBuf, amt, offset, pFile->locktype));
-+#define osGetNativeSystemInfo ((VOID(WINAPI*)( \
-+        LPSYSTEM_INFO))aSyscall[69].pCurrent)
- 
--#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 file=%p, rc=SQLITE_OK\n", 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;
--    }
--  }
-+#if defined(SQLITE_WIN32_HAS_ANSI)
-+  { "OutputDebugStringA",      (SYSCALL)OutputDebugStringA,      0 },
-+#else
-+  { "OutputDebugStringA",      (SYSCALL)0,                       0 },
- #endif
- 
--#if SQLITE_OS_WINCE
--  rc = seekWinFile(pFile, offset);
--  if( rc==0 ){
-+#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[70].pCurrent)
-+
-+#if defined(SQLITE_WIN32_HAS_WIDE)
-+  { "OutputDebugStringW",      (SYSCALL)OutputDebugStringW,      0 },
- #else
--  {
--#endif
--#if !SQLITE_OS_WINCE
--    OVERLAPPED overlapped;        /* The offset for WriteFile. */
-+  { "OutputDebugStringW",      (SYSCALL)0,                       0 },
- #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() */
- 
--#if !SQLITE_OS_WINCE
--    memset(&overlapped, 0, sizeof(OVERLAPPED));
--    overlapped.Offset = (LONG)(offset & 0xffffffff);
--    overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
--#endif
-+#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[71].pCurrent)
- 
--    while( nRem>0 ){
--#if SQLITE_OS_WINCE
--      if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){
-+  { "GetProcessHeap",          (SYSCALL)GetProcessHeap,          0 },
-+
-+#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[72].pCurrent)
-+
-+#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
-+  { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
- #else
--      if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){
-+  { "CreateFileMappingFromApp", (SYSCALL)0,                      0 },
- #endif
--        if( retryIoerr(&nRetry, &lastErrno) ) continue;
--        break;
-+
-+#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
-+        LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[73].pCurrent)
-+
-+}; /* End of the overrideable system calls */
-+
-+/*
-+** 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;
-+
-+  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;
-       }
--      assert( nWrite==0 || nWrite<=(DWORD)nRem );
--      if( nWrite==0 || nWrite>(DWORD)nRem ){
--        lastErrno = osGetLastError();
-+    }
-+  }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;
-       }
--#if !SQLITE_OS_WINCE
--      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 file=%p, rc=SQLITE_FULL\n", pFile->h));
--      return SQLITE_FULL;
-     }
--    OSTRACE(("WRITE file=%p, rc=SQLITE_IOERR_WRITE\n", pFile->h));
--    return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno,
--             "winWrite", pFile->zPath);
--  }else{
--    logIoerr(nRetry);
-   }
--  OSTRACE(("WRITE file=%p, rc=SQLITE_OK\n", pFile->h));
--  return SQLITE_OK;
-+  return rc;
- }
- 
- /*
--** Truncate an open file to a specified size
-+** 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 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 file=%p, size=%lld, lock=%d\n",
--           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
--  ** 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;
--  }
--
--  /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
--  if( seekWinFile(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);
--  }
-+static sqlite3_syscall_ptr winGetSystemCall(
-+  sqlite3_vfs *pNotUsed,
-+  const char *zName
-+){
-+  unsigned int i;
- 
--#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;
-+  UNUSED_PARAMETER(pNotUsed);
-+  for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
-+    if( strcmp(zName, aSyscall[i].zName)==0 ) return aSyscall[i].pCurrent;
-   }
--#endif
--
--  OSTRACE(("TRUNCATE file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
--  return rc;
-+  return 0;
- }
- 
--#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.
--*/
--SQLITE_API int sqlite3_sync_count = 0;
--SQLITE_API int sqlite3_fullsync_count = 0;
--#endif
--
- /*
--** Make sure all writes to a particular file are committed to disk.
-+** 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 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_TEST) && defined(SQLITE_DEBUG))
--  /*
--  ** 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
--  );
-+static const char *winNextSystemCall(sqlite3_vfs *p, const char *zName){
-+  int i = -1;
- 
--  /* 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 );
-+  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;
-+}
- 
--  OSTRACE(("SYNC file=%p, flags=%x, lock=%d\n",
--           pFile->h, flags, pFile->locktype));
-+/*
-+** This function outputs the specified (ANSI) string to the Win32 debugger
-+** (if available).
-+*/
- 
--#ifndef SQLITE_TEST
--  UNUSED_PARAMETER(flags);
--#else
--  if( (flags&0x0F)==SQLITE_SYNC_FULL ){
--    sqlite3_fullsync_count++;
-+SQLITE_API void 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);
-   }
--  sqlite3_sync_count++;
--#endif
--
--  /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
--  ** no-op
--  */
--#ifdef SQLITE_NO_SYNC
--  return SQLITE_OK;
-+#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);
- #else
--  rc = osFlushFileBuffers(pFile->h);
--  SimulateIOError( rc=FALSE );
--  if( rc ){
--    OSTRACE(("SYNC file=%p, rc=SQLITE_OK\n", pFile->h));
--    return SQLITE_OK;
-+  if( nMin>0 ){
-+    memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
-+    memcpy(zDbgBuf, zBuf, nMin);
-+    fprintf(stderr, "%s", zDbgBuf);
-   }else{
--    pFile->lastErrno = osGetLastError();
--    OSTRACE(("SYNC file=%p, rc=SQLITE_IOERR_FSYNC\n", pFile->h));
--    return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno,
--             "winSync", pFile->zPath);
-+    fprintf(stderr, "%s", zBuf);
-   }
- #endif
- }
- 
- /*
--** Determine the current size of a file in bytes
-+** The following routine suspends the current thread for at least ms
-+** milliseconds.  This is equivalent to the Win32 Sleep() interface.
- */
--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));
-+#if SQLITE_OS_WINRT
-+static HANDLE sleepObj = NULL;
-+#endif
- 
-+SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){
- #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);
--    }
-+  if ( sleepObj==NULL ){
-+    sleepObj = osCreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET,
-+                                SYNCHRONIZE);
-   }
-+  assert( sleepObj!=NULL );
-+  osWaitForSingleObjectEx(sleepObj, milliseconds, FALSE);
- #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);
--    }
--  }
-+  osSleep(milliseconds);
- #endif
--  OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n",
--           pFile->h, pSize, *pSize, sqlite3ErrName(rc)));
--  return rc;
- }
- 
- /*
--** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
-+** 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.
- */
--#ifndef LOCKFILE_FAIL_IMMEDIATELY
--# define LOCKFILE_FAIL_IMMEDIATELY 1
--#endif
--
--#ifndef LOCKFILE_EXCLUSIVE_LOCK
--# define LOCKFILE_EXCLUSIVE_LOCK 2
-+#if SQLITE_OS_WINCE || SQLITE_OS_WINRT
-+# define isNT()  (1)
-+#elif !defined(SQLITE_WIN32_HAS_WIDE)
-+# define isNT()  (0)
-+#else
-+  static int isNT(void){
-+    if( sqlite3_os_type==0 ){
-+      OSVERSIONINFOA sInfo;
-+      sInfo.dwOSVersionInfoSize = sizeof(sInfo);
-+      osGetVersionExA(&sInfo);
-+      sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
-+    }
-+    return sqlite3_os_type==2;
-+  }
- #endif
- 
-+#ifdef SQLITE_WIN32_MALLOC
- /*
--** 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.
-+** Allocate nBytes of memory.
- */
--#ifndef SQLITE_LOCKFILE_FLAGS
--# define SQLITE_LOCKFILE_FLAGS   (LOCKFILE_FAIL_IMMEDIATELY | \
--                                  LOCKFILE_EXCLUSIVE_LOCK)
-+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 (%d), heap=%p",
-+                nBytes, osGetLastError(), (void*)hHeap);
-+  }
-+  return p;
-+}
- 
- /*
--** Currently, SQLite never calls the LockFileEx function without wanting the
--** call to fail immediately if the lock cannot be obtained.
-+** Free memory.
- */
--#ifndef SQLITE_LOCKFILEEX_FLAGS
--# define SQLITE_LOCKFILEEX_FLAGS (LOCKFILE_FAIL_IMMEDIATELY)
-+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 (%d), heap=%p",
-+                pPrior, osGetLastError(), (void*)hHeap);
-+  }
-+}
- 
- /*
--** Acquire a reader lock.
--** Different API routines are called depending on whether or not this
--** is Win9x or WinNT.
-+** Change the size of an existing memory allocation
- */
--static int getReadLock(winFile *pFile){
--  int res;
--  OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype));
--  if( isNT() ){
--#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);
-+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);
-   }
--#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 */
-+  if( !p ){
-+    sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%d), heap=%p",
-+                pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, osGetLastError(),
-+                (void*)hHeap);
-   }
--  OSTRACE(("READ-LOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res)));
--  return res;
-+  return p;
- }
- 
- /*
--** Undo a readlock
-+** Return the size of an outstanding allocation, in bytes.
- */
--static int unlockReadLock(winFile *pFile){
--  int res;
--  DWORD lastErrno;
--  OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype));
--  if( isNT() ){
--    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);
--  }
-+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, NULL) );
- #endif
--  if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){
--    pFile->lastErrno = lastErrno;
--    winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno,
--             "unlockReadLock", pFile->zPath);
-+  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 (%d), heap=%p",
-+                p, osGetLastError(), (void*)hHeap);
-+    return 0;
-   }
--  OSTRACE(("READ-UNLOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res)));
--  return res;
-+  return (int)n;
- }
- 
- /*
--** 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.
-+** Round up a request size to the next valid allocation size.
- */
--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;
--
--  assert( id!=0 );
--  OSTRACE(("LOCK file=%p, oldLock=%d(%d), newLock=%d\n",
--           pFile->h, pFile->locktype, pFile->sharedLockByte, locktype));
-+static int winMemRoundup(int n){
-+  return n;
-+}
- 
--  /* 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;
--  }
-+/*
-+** Initialize this module.
-+*/
-+static int winMemInit(void *pAppData){
-+  winMemData *pWinMemData = (winMemData *)pAppData;
- 
--  /* 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( !pWinMemData ) return SQLITE_ERROR;
-+  assert( pWinMemData->magic==WINMEM_MAGIC );
- 
--  /* 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.
--      */
--      OSTRACE(("LOCK-PENDING-FAIL file=%p, count=%d, rc=%s\n",
--               pFile->h, cnt, sqlite3ErrName(res)));
--      if( cnt ) sqlite3_win32_sleep(1);
--    }
--    gotPendingLock = res;
--    if( !res ){
--      lastErrno = osGetLastError();
-+#if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE
-+  if( !pWinMemData->hHeap ){
-+    pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS,
-+                                      SQLITE_WIN32_HEAP_INIT_SIZE,
-+                                      SQLITE_WIN32_HEAP_MAX_SIZE);
-+    if( !pWinMemData->hHeap ){
-+      sqlite3_log(SQLITE_NOMEM,
-+          "failed to HeapCreate (%d), flags=%u, initSize=%u, maxSize=%u",
-+          osGetLastError(), SQLITE_WIN32_HEAP_FLAGS,
-+          SQLITE_WIN32_HEAP_INIT_SIZE, SQLITE_WIN32_HEAP_MAX_SIZE);
-+      return SQLITE_NOMEM;
-     }
-+    pWinMemData->bOwned = TRUE;
-+    assert( pWinMemData->bOwned );
-   }
--
--  /* Acquire a shared lock
--  */
--  if( locktype==SHARED_LOCK && res ){
--    assert( pFile->locktype==NO_LOCK );
--    res = getReadLock(pFile);
--    if( res ){
--      newLocktype = SHARED_LOCK;
--    }else{
--      lastErrno = osGetLastError();
--    }
-+#else
-+  pWinMemData->hHeap = osGetProcessHeap();
-+  if( !pWinMemData->hHeap ){
-+    sqlite3_log(SQLITE_NOMEM,
-+        "failed to GetProcessHeap (%d)", osGetLastError());
-+    return SQLITE_NOMEM;
-   }
-+  pWinMemData->bOwned = FALSE;
-+  assert( !pWinMemData->bOwned );
-+#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) );
-+#endif
-+  return SQLITE_OK;
-+}
- 
--  /* 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();
-+/*
-+** Deinitialize this module.
-+*/
-+static void winMemShutdown(void *pAppData){
-+  winMemData *pWinMemData = (winMemData *)pAppData;
-+
-+  if( !pWinMemData ) return;
-+  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
-+    if( pWinMemData->bOwned ){
-+      if( !osHeapDestroy(pWinMemData->hHeap) ){
-+        sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%d), heap=%p",
-+                    osGetLastError(), (void*)pWinMemData->hHeap);
-+      }
-+      pWinMemData->bOwned = FALSE;
-     }
-+    pWinMemData->hHeap = NULL;
-   }
-+}
- 
--  /* Acquire a PENDING lock
--  */
--  if( locktype==EXCLUSIVE_LOCK && res ){
--    newLocktype = PENDING_LOCK;
--    gotPendingLock = 0;
--  }
-+/*
-+** 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;
-+}
- 
--  /* Acquire an EXCLUSIVE lock
--  */
--  if( locktype==EXCLUSIVE_LOCK && res ){
--    assert( pFile->locktype>=SHARED_LOCK );
--    res = unlockReadLock(pFile);
--    res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0,
--                      SHARED_SIZE, 0);
--    if( res ){
--      newLocktype = EXCLUSIVE_LOCK;
--    }else{
--      lastErrno = osGetLastError();
--      getReadLock(pFile);
--    }
--  }
-+SQLITE_PRIVATE void sqlite3MemSetDefault(void){
-+  sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetWin32());
-+}
-+#endif /* SQLITE_WIN32_MALLOC */
-+
-+/*
-+** Convert a UTF-8 string to Microsoft Unicode (UTF-16?). 
-+**
-+** Space to hold the returned string is obtained from malloc.
-+*/
-+static LPWSTR utf8ToUnicode(const char *zFilename){
-+  int nChar;
-+  LPWSTR zWideFilename;
- 
--  /* 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);
-+  nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
-+  if( nChar==0 ){
-+    return 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{
--    OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n",
--             pFile->h, locktype, newLocktype));
--    pFile->lastErrno = lastErrno;
--    rc = SQLITE_BUSY;
-+  zWideFilename = sqlite3MallocZero( nChar*sizeof(zWideFilename[0]) );
-+  if( zWideFilename==0 ){
-+    return 0;
-   }
--  pFile->locktype = (u8)newLocktype;
--  OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n",
--           pFile->h, pFile->locktype, sqlite3ErrName(rc)));
--  return rc;
-+  nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename,
-+                                nChar);
-+  if( nChar==0 ){
-+    sqlite3_free(zWideFilename);
-+    zWideFilename = 0;
-+  }
-+  return zWideFilename;
- }
- 
- /*
--** 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.
-+** Convert Microsoft Unicode to UTF-8.  Space to hold the returned string is
-+** obtained from sqlite3_malloc().
- */
--static int winCheckReservedLock(sqlite3_file *id, int *pResOut){
--  int rc;
--  winFile *pFile = (winFile*)id;
--
--  SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
--  OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p\n", pFile->h, pResOut));
-+static char *unicodeToUtf8(LPCWSTR zWideFilename){
-+  int nByte;
-+  char *zFilename;
- 
--  assert( id!=0 );
--  if( pFile->locktype>=RESERVED_LOCK ){
--    rc = 1;
--    OSTRACE(("TEST-WR-LOCK file=%p, rc=%d (local)\n", pFile->h, rc));
--  }else{
--    rc = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE, 0, 1, 0);
--    if( rc ){
--      winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
--    }
--    rc = !rc;
--    OSTRACE(("TEST-WR-LOCK file=%p, rc=%d (remote)\n", pFile->h, rc));
-+  nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
-+  if( nByte == 0 ){
-+    return 0;
-   }
--  *pResOut = rc;
--  OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n",
--           pFile->h, pResOut, *pResOut));
--  return SQLITE_OK;
-+  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;
- }
- 
- /*
--** 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;
-+** 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 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 && !getReadLock(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( type>=RESERVED_LOCK ){
--    winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
-+static LPWSTR mbcsToUnicode(const char *zFilename){
-+  int nByte;
-+  LPWSTR zMbcsFilename;
-+  int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
-+
-+  nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL,
-+                                0)*sizeof(WCHAR);
-+  if( nByte==0 ){
-+    return 0;
-   }
--  if( locktype==NO_LOCK && type>=SHARED_LOCK ){
--    unlockReadLock(pFile);
-+  zMbcsFilename = sqlite3MallocZero( nByte*sizeof(zMbcsFilename[0]) );
-+  if( zMbcsFilename==0 ){
-+    return 0;
-   }
--  if( type>=PENDING_LOCK ){
--    winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
-+  nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename,
-+                                nByte);
-+  if( nByte==0 ){
-+    sqlite3_free(zMbcsFilename);
-+    zMbcsFilename = 0;
-   }
--  pFile->locktype = (u8)locktype;
--  OSTRACE(("UNLOCK file=%p, lock=%d, rc=%s\n",
--           pFile->h, pFile->locktype, sqlite3ErrName(rc)));
--  return rc;
-+  return zMbcsFilename;
- }
- 
- /*
--** If *pArg is inititially negative then this is a query.  Set *pArg to
--** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set.
-+** Convert Microsoft Unicode to multi-byte character string, based on the
-+** user's ANSI codepage.
- **
--** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags.
-+** Space to hold the returned string is obtained from
-+** sqlite3_malloc().
- */
--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 char *unicodeToMbcs(LPCWSTR zWideFilename){
-+  int nByte;
-+  char *zFilename;
-+  int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
-+
-+  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;
- }
- 
--/* Forward declaration */
--static int getTempname(int nBuf, char *zBuf);
--
- /*
--** Control and query of the open file handle.
-+** Convert multibyte character string to UTF-8.  Space to hold the
-+** returned string is obtained from sqlite3_malloc().
- */
--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("win32");
--      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 ){
--        win32IoerrRetry = a[0];
--      }else{
--        a[0] = win32IoerrRetry;
--      }
--      if( a[1]>0 ){
--        win32IoerrRetryDelay = a[1];
--      }else{
--        a[1] = win32IoerrRetryDelay;
--      }
--      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
--      return SQLITE_OK;
--    }
--    case SQLITE_FCNTL_TEMPFILENAME: {
--      char *zTFile = sqlite3MallocZero( pFile->pVfs->mxPathname );
--      if( zTFile ){
--        getTempname(pFile->pVfs->mxPathname, zTFile);
--        *(char**)pArg = zTFile;
--      }
--      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
--      return SQLITE_OK;
--    }
--#if SQLITE_MAX_MMAP_SIZE>0
--    case SQLITE_FCNTL_MMAP_SIZE: {
--      i64 newLimit = *(i64*)pArg;
--      if( newLimit>sqlite3GlobalConfig.mxMmap ){
--        newLimit = sqlite3GlobalConfig.mxMmap;
--      }
--      *(i64*)pArg = pFile->mmapSizeMax;
--      if( newLimit>=0 ) pFile->mmapSizeMax = newLimit;
--      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
--      return SQLITE_OK;
--    }
--#endif
-+SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){
-+  char *zFilenameUtf8;
-+  LPWSTR zTmpWide;
-+
-+  zTmpWide = mbcsToUnicode(zFilename);
-+  if( zTmpWide==0 ){
-+    return 0;
-   }
--  OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h));
--  return SQLITE_NOTFOUND;
-+  zFilenameUtf8 = unicodeToUtf8(zTmpWide);
-+  sqlite3_free(zTmpWide);
-+  return zFilenameUtf8;
- }
- 
- /*
--** 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.
-+** Convert UTF-8 to multibyte character string.  Space to hold the 
-+** returned string is obtained from sqlite3_malloc().
- */
--static int winSectorSize(sqlite3_file *id){
--  (void)id;
--  return SQLITE_DEFAULT_SECTOR_SIZE;
-+SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){
-+  char *zFilenameMbcs;
-+  LPWSTR zTmpWide;
-+
-+  zTmpWide = utf8ToUnicode(zFilename);
-+  if( zTmpWide==0 ){
-+    return 0;
-+  }
-+  zFilenameMbcs = unicodeToMbcs(zTmpWide);
-+  sqlite3_free(zTmpWide);
-+  return zFilenameMbcs;
- }
- 
- /*
--** Return a vector of device characteristics.
-+** 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.
- */
--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);
-+SQLITE_API int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
-+  char **ppDirectory = 0;
-+#ifndef SQLITE_OMIT_AUTOINIT
-+  int rc = sqlite3_initialize();
-+  if( rc ) return rc;
-+#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 = unicodeToUtf8(zValue);
-+      if ( zValueUtf8==0 ){
-+        return SQLITE_NOMEM;
-+      }
-+    }
-+    sqlite3_free(*ppDirectory);
-+    *ppDirectory = zValueUtf8;
-+    return SQLITE_OK;
-+  }
-+  return SQLITE_ERROR;
- }
- 
--/* 
--** 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.
--*/
--SYSTEM_INFO winSysInfo;
--
--#ifndef SQLITE_OMIT_WAL
--
- /*
--** 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()
-+** The return value of getLastErrorMsg
-+** is zero if the error message fits in the buffer, or non-zero
-+** otherwise (if the message was truncated).
- */
--static void winShmEnterMutex(void){
--  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
--}
--static void winShmLeaveMutex(void){
--  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
--}
--#ifdef SQLITE_DEBUG
--static int winShmMutexHeld(void) {
--  return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
--}
-+static int getLastErrorMsg(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( isNT() ){
-+#if SQLITE_OS_WINRT
-+    WCHAR zTempWide[MAX_PATH+1]; /* NOTE: Somewhat arbitrary. */
-+    dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
-+                             FORMAT_MESSAGE_IGNORE_INSERTS,
-+                             NULL,
-+                             lastErrno,
-+                             0,
-+                             zTempWide,
-+                             MAX_PATH,
-+                             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 = unicodeToUtf8(zTempWide);
-+      sqlite3EndBenignMalloc();
-+#if !SQLITE_OS_WINRT
-+      /* free the system buffer allocated by FormatMessage */
-+      osLocalFree(zTempWide);
- #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);
-+    }
-+  }
-+#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;
-+}
- 
- /*
--** 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
-+** This function - winLogErrorAtLine() - is only ever called via the macro
-+** winLogError().
- **
--** Either winShmNode.mutex must be held or winShmNode.nRef==0 and
--** winShmMutexHeld() is true when reading or writing any other field
--** in this structure.
-+** 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.
- */
--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 */
-+#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 */
- 
--  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
--  u8 nextShmId;              /* Next available winShm.id value */
--#endif
--};
-+  zMsg[0] = 0;
-+  getLastErrorMsg(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
-+  );
- 
--/*
--** A global array of all winShmNode objects.
--**
--** The winShmMutexHeld() must be true while reading or writing this list.
--*/
--static winShmNode *winShmNodeList = 0;
-+  return errcode;
-+}
- 
- /*
--** 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.
-+** 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.
- */
--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 */
--#ifdef SQLITE_DEBUG
--  u8 id;                     /* Id of this connection with its winShmNode */
-+#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 win32IoerrRetry = SQLITE_WIN32_IOERR_RETRY;
-+static int win32IoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY;
- 
- /*
--** Constants used for locking
-+** 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.
- */
--#define WIN_SHM_BASE   ((22+SQLITE_SHM_NLOCK)*4)        /* first lock byte */
--#define WIN_SHM_DMS    (WIN_SHM_BASE+SQLITE_SHM_NLOCK)  /* deadman switch */
-+static int retryIoerr(int *pnRetry, DWORD *pError){
-+  DWORD e = osGetLastError();
-+  if( *pnRetry>=win32IoerrRetry ){
-+    if( pError ){
-+      *pError = e;
-+    }
-+    return 0;
-+  }
-+  if( e==ERROR_ACCESS_DENIED ||
-+      e==ERROR_LOCK_VIOLATION ||
-+      e==ERROR_SHARING_VIOLATION ){
-+    sqlite3_win32_sleep(win32IoerrRetryDelay*(1+*pnRetry));
-+    ++*pnRetry;
-+    return 1;
-+  }
-+  if( pError ){
-+    *pError = e;
-+  }
-+  return 0;
-+}
- 
- /*
--** Apply advisory locks for all n bytes beginning at ofst.
-+** Log a I/O error retry episode.
- */
--#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() */
--
--  /* Access to the winShmNode object is serialized by the caller */
--  assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 );
--
--  OSTRACE(("SHM-LOCK file=%p, lock=%d, offset=%d, size=%d\n",
--           pFile->hFile.h, lockType, ofst, nByte));
--
--  /* 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);
--  }
--  
--  if( rc!= 0 ){
--    rc = SQLITE_OK;
--  }else{
--    pFile->lastErrno =  osGetLastError();
--    rc = SQLITE_BUSY;
-+static void logIoerr(int nRetry){
-+  if( nRetry ){
-+    sqlite3_log(SQLITE_IOERR, 
-+      "delayed %dms for lock/sharing conflict",
-+      win32IoerrRetryDelay*nRetry*(nRetry+1)/2
-+    );
-   }
-+}
- 
--  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
-+/*************************************************************************
-+** 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;
- }
-+#endif
- 
--/* Forward references to VFS methods */
--static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*);
--static int winDelete(sqlite3_vfs *,const char*,int);
-+#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)]
- 
- /*
--** 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.
-+** Acquire a lock on the handle h
- */
--static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
--  winShmNode **pp;
--  winShmNode *p;
--  BOOL bRc;
--  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++){
--        bRc = osUnmapViewOfFile(p->aRegion[i].pMap);
--        OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n",
--                 osGetCurrentProcessId(), i, bRc ? "ok" : "failed"));
--        bRc = osCloseHandle(p->aRegion[i].hMap);
--        OSTRACE(("SHM-PURGE-CLOSE pid=%lu, region=%d, rc=%s\n",
--                 osGetCurrentProcessId(), i, bRc ? "ok" : "failed"));
--      }
--      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;
--    }
--  }
-+static void winceMutexAcquire(HANDLE h){
-+   DWORD dwErr;
-+   do {
-+     dwErr = osWaitForSingleObject(h, INFINITE);
-+   } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);
- }
--
- /*
--** 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.
-+** Release a lock acquired by winceMutexAcquire()
- */
--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 */
-+#define winceMutexRelease(h) ReleaseMutex(h)
- 
--  assert( pDbFd->pShm==0 );    /* Not previously opened */
-+/*
-+** 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;
- 
--  /* Allocate space for the new sqlite3_shm object.  Also speculatively
--  ** allocate space for a new winShmNode and filename.
--  */
--  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);
-+  zName = utf8ToUnicode(zFilename);
-+  if( zName==0 ){
-+    /* out of memory */
-     return SQLITE_IOERR_NOMEM;
-   }
--  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.
-+  /* Initialize the local lockdata */
-+  memset(&pFile->local, 0, sizeof(pFile->local));
-+
-+  /* Replace the backslashes from the filename and lowercase it
-+  ** to derive a mutex name. */
-+  zTok = osCharLowerW(zName);
-+  for (;*zTok;zTok++){
-+    if (*zTok == '\\') *zTok = '_';
-+  }
-+
-+  /* Create/open the named mutex */
-+  pFile->hMutex = osCreateMutexW(NULL, FALSE, zName);
-+  if (!pFile->hMutex){
-+    pFile->lastErrno = osGetLastError();
-+    winLogError(SQLITE_IOERR, pFile->lastErrno,
-+                "winceCreateLock1", zFilename);
-+    sqlite3_free(zName);
-+    return SQLITE_IOERR;
-+  }
-+
-+  /* Acquire the mutex before continuing */
-+  winceMutexAcquire(pFile->hMutex);
-+  
-+  /* 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.
-   */
--  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;
-+  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;
-   }
--  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;
--    }
-+  sqlite3_free(zName);
- 
--    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 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;
-     }
-+  }
- 
--    /* 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 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;
-     }
--    if( rc ) goto shm_open_err;
-+    winceMutexRelease(pFile->hMutex);
-+    osCloseHandle(pFile->hMutex);
-+    pFile->hMutex = NULL;
-+    return SQLITE_IOERR;
-+  }
-+  
-+  /* Initialize the shared memory if we're supposed to */
-+  if( bInit ){
-+    memset(pFile->shared, 0, sizeof(winceLock));
-   }
- 
--  /* Make the new connection a child of the winShmNode */
--  p->pShmNode = pShmNode;
--#ifdef SQLITE_DEBUG
--  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);
-+  winceMutexRelease(pFile->hMutex);
-   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();
--  return rc;
- }
- 
- /*
--** Close a connection to shared-memory.  Delete the underlying 
--** storage if deleteFlag is true.
-+** Destroy the part of winFile that deals with wince locks
- */
--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 */
--
--  pDbFd = (winFile*)fd;
--  p = pDbFd->pShm;
--  if( p==0 ) return SQLITE_OK;
--  pShmNode = p->pShmNode;
-+static void winceDestroyLock(winFile *pFile){
-+  if (pFile->hMutex){
-+    /* Acquire the mutex */
-+    winceMutexAcquire(pFile->hMutex);
- 
--  /* 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;
-+    /* 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;
-+    }
-+    if (pFile->local.bExclusive){
-+      pFile->shared->bExclusive = FALSE;
-+    }
- 
--  /* Free the connection p */
--  sqlite3_free(p);
--  pDbFd->pShm = 0;
--  sqlite3_mutex_leave(pShmNode->mutex);
-+    /* De-reference and close our copy of the shared memory handle */
-+    osUnmapViewOfFile(pFile->shared);
-+    osCloseHandle(pFile->hShared);
- 
--  /* 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);
-+    /* Done with the mutex */
-+    winceMutexRelease(pFile->hMutex);    
-+    osCloseHandle(pFile->hMutex);
-+    pFile->hMutex = NULL;
-   }
--  winShmLeaveMutex();
--
--  return SQLITE_OK;
- }
- 
--/*
--** Change the lock state for a shared-memory segment.
-+/* 
-+** An implementation of the LockFile() API of Windows for CE
- */
--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 */
-+static BOOL winceLockFile(
-+  LPHANDLE phFile,
-+  DWORD dwFileOffsetLow,
-+  DWORD dwFileOffsetHigh,
-+  DWORD nNumberOfBytesToLockLow,
-+  DWORD nNumberOfBytesToLockHigh
- ){
--  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 */
-+  winFile *pFile = HANDLE_TO_WINFILE(phFile);
-+  BOOL bReturn = FALSE;
- 
--  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 );
-+  UNUSED_PARAMETER(dwFileOffsetHigh);
-+  UNUSED_PARAMETER(nNumberOfBytesToLockHigh);
- 
--  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 (!pFile->hMutex) return TRUE;
-+  winceMutexAcquire(pFile->hMutex);
- 
--    /* 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;
-+  /* 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;
-+    }
-+  }
-+
-+  /* 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;
-+    }
-+  }
-+
-+  /* 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;
-     }
-+  }
- 
--    /* Unlock the system-level locks */
--    if( (mask & allMask)==0 ){
--      rc = winShmSystemLock(pShmNode, _SHM_UNLCK, ofst+WIN_SHM_BASE, n);
--    }else{
--      rc = SQLITE_OK;
-+  /* 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;
-     }
-+  }
- 
--    /* 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" */
-+  winceMutexRelease(pFile->hMutex);
-+  return bReturn;
-+}
- 
--    /* 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;
-+/*
-+** An implementation of the UnlockFile API of Windows for CE
-+*/
-+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);
-+
-+  /* 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;
-     }
- 
--    /* 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;
-+    /* 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;
-     }
-+  }
- 
--    /* 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;
--      }
-+  /* 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;
-     }
--  
--    /* 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;
--      }
-+  }
-+  /* 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;
-     }
-   }
--  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;
-+
-+  winceMutexRelease(pFile->hMutex);
-+  return bReturn;
- }
-+/*
-+** End of the special code for wince
-+*****************************************************************************/
-+#endif /* SQLITE_OS_WINCE */
- 
- /*
--** 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.
-+** Lock a file region.
- */
--static void winShmBarrier(
--  sqlite3_file *fd          /* Database holding the shared memory */
-+static BOOL winLockFile(
-+  LPHANDLE phFile,
-+  DWORD flags,
-+  DWORD offsetLow,
-+  DWORD offsetHigh,
-+  DWORD numBytesLow,
-+  DWORD numBytesHigh
- ){
--  UNUSED_PARAMETER(fd);
--  /* MemoryBarrier(); // does not work -- do not know why not */
--  winShmEnterMutex();
--  winShmLeaveMutex();
-+#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( isNT() ){
-+    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
- }
- 
- /*
--** 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 */
-+** Unlock a file region.
-+ */
-+static BOOL winUnlockFile(
-+  LPHANDLE phFile,
-+  DWORD offsetLow,
-+  DWORD offsetHigh,
-+  DWORD numBytesLow,
-+  DWORD numBytesHigh
- ){
--  winFile *pDbFd = (winFile*)fd;
--  winShm *p = pDbFd->pShm;
--  winShmNode *pShmNode;
--  int rc = SQLITE_OK;
-+#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( isNT() ){
-+    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
-+}
- 
--  if( !p ){
--    rc = winOpenSharedMemory(pDbFd);
--    if( rc!=SQLITE_OK ) return rc;
--    p = pDbFd->pShm;
-+/*****************************************************************************
-+** The next group of routines implement the I/O methods specified
-+** by the sqlite3_io_methods object.
-+******************************************************************************/
-+
-+/*
-+** Some Microsoft compilers lack this definition.
-+*/
-+#ifndef INVALID_SET_FILE_POINTER
-+# define INVALID_SET_FILE_POINTER ((DWORD)-1)
-+#endif
-+
-+/*
-+** 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 int seekWinFile(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));
-+
-+  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,
-+             "seekWinFile", pFile->zPath);
-+    OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
-+    return 1;
-   }
--  pShmNode = p->pShmNode;
- 
--  sqlite3_mutex_enter(pShmNode->mutex);
--  assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
-+  OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h));
-+  return 0;
-+#else
-+  /*
-+  ** Same as above, except that this implementation works for WinRT.
-+  */
- 
--  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 */
-+  LARGE_INTEGER x;                /* The new offset */
-+  BOOL bRet;                      /* Value returned by SetFilePointerEx() */
- 
--    pShmNode->szRegion = szRegion;
-+  x.QuadPart = iOffset;
-+  bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN);
- 
--    /* 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(!bRet){
-+    pFile->lastErrno = osGetLastError();
-+    winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
-+             "seekWinFile", pFile->zPath);
-+    OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
-+    return 1;
-+  }
- 
--    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;
--      }
--    }
-+  OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h));
-+  return 0;
-+#endif
-+}
- 
--    /* Map the requested memory region into this processes address space. */
--    apNew = (struct ShmRegion *)sqlite3_realloc(
--        pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
--    );
--    if( !apNew ){
--      rc = SQLITE_IOERR_NOMEM;
--      goto shmpage_out;
--    }
--    pShmNode->aRegion = apNew;
-+#if SQLITE_MAX_MMAP_SIZE>0
-+/* Forward references to VFS methods */
-+static int winUnmapfile(winFile*);
-+#endif
- 
--    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
--      );
-+/*
-+** 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.
-+*/
-+#define MX_CLOSE_ATTEMPT 3
-+static int winClose(sqlite3_file *id){
-+  int rc, cnt = 0;
-+  winFile *pFile = (winFile*)id;
-+
-+  assert( id!=0 );
-+#ifndef SQLITE_OMIT_WAL
-+  assert( pFile->pShm==0 );
- #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
--        );
-+  assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE );
-+  OSTRACE(("CLOSE file=%p\n", pFile->h));
-+
-+#if SQLITE_MAX_MMAP_SIZE>0
-+  rc = winUnmapfile(pFile);
-+  if( rc!=SQLITE_OK ) return rc;
- #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;
--      }
- 
--      pShmNode->aRegion[pShmNode->nRegion].pMap = pMap;
--      pShmNode->aRegion[pShmNode->nRegion].hMap = hMap;
--      pShmNode->nRegion++;
-+  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);
-   }
--
--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{
--    *pp = 0;
-+#endif
-+  if( rc ){
-+    pFile->h = NULL;
-   }
--  sqlite3_mutex_leave(pShmNode->mutex);
--  return rc;
-+  OpenCounter(-1);
-+  OSTRACE(("CLOSE file=%p, rc=%s\n", pFile->h, rc ? "ok" : "failed"));
-+  return rc ? SQLITE_OK
-+            : winLogError(SQLITE_IOERR_CLOSE, osGetLastError(),
-+                          "winClose", pFile->zPath);
- }
- 
--#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.
-+** Read data from a file into a buffer.  Return SQLITE_OK if all
-+** bytes were read successfully and SQLITE_IOERR if anything goes
-+** wrong.
- */
-+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
-+  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 */
-+
-+  assert( id!=0 );
-+  assert( amt>0 );
-+  assert( offset>=0 );
-+  SimulateIOError(return SQLITE_IOERR_READ);
-+  OSTRACE(("READ file=%p, buffer=%p, amount=%d, offset=%lld, lock=%d\n",
-+           pFile->h, pBuf, amt, offset, pFile->locktype));
-+
- #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,
--                         "winUnmap1", pFile->zPath);
-+  /* 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 file=%p, rc=SQLITE_OK\n", 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;
-     }
--    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,
--                         "winUnmap2", pFile->zPath);
--    }
--    pFile->hMap = NULL;
-+#endif
-+
-+#if SQLITE_OS_WINCE
-+  if( seekWinFile(pFile, offset) ){
-+    OSTRACE(("READ file=%p, rc=SQLITE_FULL\n", 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( retryIoerr(&nRetry, &lastErrno) ) continue;
-+    pFile->lastErrno = lastErrno;
-+    OSTRACE(("READ file=%p, rc=SQLITE_IOERR_READ\n", pFile->h));
-+    return winLogError(SQLITE_IOERR_READ, pFile->lastErrno,
-+             "winRead", pFile->zPath);
-+  }
-+  logIoerr(nRetry);
-+  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));
-+    return SQLITE_IOERR_SHORT_READ;
-   }
--  OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
--           osGetCurrentProcessId(), pFile));
-+
-+  OSTRACE(("READ file=%p, rc=SQLITE_OK\n", pFile->h));
-   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.
--**
--** 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.
-+** Write data from a buffer into a file.  Return SQLITE_OK on success
-+** or some other error code on failure.
- */
--static int winMapfile(winFile *pFd, sqlite3_int64 nByte){
--  sqlite3_int64 nMap = nByte;
--  int rc;
-+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( nMap>=0 || pFd->nFetchOut==0 );
--  OSTRACE(("MAP-FILE pid=%lu, pFile=%p, size=%lld\n",
--           osGetCurrentProcessId(), pFd, nByte));
-+  assert( amt>0 );
-+  assert( pFile );
-+  SimulateIOError(return SQLITE_IOERR_WRITE);
-+  SimulateDiskfullError(return SQLITE_FULL);
- 
--  if( pFd->nFetchOut>0 ) return SQLITE_OK;
-+  OSTRACE(("WRITE file=%p, buffer=%p, amount=%d, offset=%lld, lock=%d\n",
-+           pFile->h, pBuf, amt, offset, pFile->locktype));
- 
--  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 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 file=%p, rc=SQLITE_OK\n", 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;
-     }
-   }
--  if( nMap>pFd->mmapSizeMax ){
--    nMap = pFd->mmapSizeMax;
--  }
--  nMap &= ~(sqlite3_int64)(winSysInfo.dwPageSize - 1);
-- 
--  if( nMap==0 && pFd->mmapSize>0 ){
--    winUnmapfile(pFd);
--  }
--  if( nMap!=pFd->mmapSize ){
--    void *pNew = 0;
--    DWORD protect = PAGE_READONLY;
--    DWORD flags = FILE_MAP_READ;
-+#endif
- 
--    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);
-+#if SQLITE_OS_WINCE
-+  rc = seekWinFile(pFile, offset);
-+  if( rc==0 ){
-+#else
-+  {
- #endif
--    if( pFd->hMap==NULL ){
--      pFd->lastErrno = osGetLastError();
--      rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
--                       "winMapfile", pFd->zPath);
--      /* Log the error, but continue normal operation using xRead/xWrite */
--      OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n",
--               osGetCurrentProcessId(), pFd));
--      return SQLITE_OK;
--    }
--    assert( (nMap % winSysInfo.dwPageSize)==0 );
--#if SQLITE_OS_WINRT
--    pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, nMap);
-+#if !SQLITE_OS_WINCE
-+    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() */
-+
-+#if !SQLITE_OS_WINCE
-+    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( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){
- #else
--    assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff );
--    pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap);
-+      if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){
- #endif
--    if( pNew==NULL ){
--      osCloseHandle(pFd->hMap);
--      pFd->hMap = NULL;
--      pFd->lastErrno = osGetLastError();
--      winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
--                  "winMapfile", pFd->zPath);
--      OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n",
--               osGetCurrentProcessId(), pFd));
--      return SQLITE_OK;
-+        if( retryIoerr(&nRetry, &lastErrno) ) continue;
-+        break;
-+      }
-+      assert( nWrite==0 || nWrite<=(DWORD)nRem );
-+      if( nWrite==0 || nWrite>(DWORD)nRem ){
-+        lastErrno = osGetLastError();
-+        break;
-+      }
-+#if !SQLITE_OS_WINCE
-+      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;
-     }
--    pFd->pMapRegion = pNew;
--    pFd->mmapSize = nMap;
--    pFd->mmapSizeActual = nMap;
-   }
- 
--  OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
--           osGetCurrentProcessId(), pFd));
-+  if( rc ){
-+    if(   ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL )
-+       || ( pFile->lastErrno==ERROR_DISK_FULL )){
-+      OSTRACE(("WRITE file=%p, rc=SQLITE_FULL\n", pFile->h));
-+      return SQLITE_FULL;
-+    }
-+    OSTRACE(("WRITE file=%p, rc=SQLITE_IOERR_WRITE\n", pFile->h));
-+    return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno,
-+             "winWrite", pFile->zPath);
-+  }else{
-+    logIoerr(nRetry);
-+  }
-+  OSTRACE(("WRITE file=%p, rc=SQLITE_OK\n", pFile->h));
-   return SQLITE_OK;
- }
--#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 this function does return a pointer, the caller must eventually 
--** release the reference by calling winUnfetch().
-+** Truncate an open file to a specified size
- */
--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 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;
- 
--  OSTRACE(("FETCH pid=%lu, pFile=%p, offset=%lld, amount=%d, pp=%p\n",
--           osGetCurrentProcessId(), fd, iOff, nAmt, pp));
-+  assert( pFile );
-+  SimulateIOError(return SQLITE_IOERR_TRUNCATE);
-+  OSTRACE(("TRUNCATE file=%p, size=%lld, lock=%d\n",
-+           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
-+  ** 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;
-+  }
-+
-+  /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
-+  if( seekWinFile(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 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;
--      }
--    }
--    if( pFd->mmapSize >= iOff+nAmt ){
--      *pp = &((u8 *)pFd->pMapRegion)[iOff];
--      pFd->nFetchOut++;
--    }
-+  /* 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;
-   }
- #endif
- 
--  OSTRACE(("FETCH pid=%lu, pFile=%p, pp=%p, *pp=%p, rc=SQLITE_OK\n",
--           osGetCurrentProcessId(), fd, pp, *pp));
--  return SQLITE_OK;
-+  OSTRACE(("TRUNCATE file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
-+  return rc;
- }
- 
-+#ifdef SQLITE_TEST
- /*
--** 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.
-+** 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 winUnfetch(sqlite3_file *fd, i64 iOff, void *p){
--#if SQLITE_MAX_MMAP_SIZE>0
--  winFile *pFd = (winFile*)fd;   /* The underlying database file */
-+SQLITE_API int sqlite3_sync_count = 0;
-+SQLITE_API int sqlite3_fullsync_count = 0;
-+#endif
- 
--  /* 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) );
-+/*
-+** 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_TEST) && defined(SQLITE_DEBUG))
-+  /*
-+  ** 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
- 
--  /* If p!=0, it must match the iOff value. */
--  assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] );
-+  assert( pFile );
-+  /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */
-+  assert((flags&0x0F)==SQLITE_SYNC_NORMAL
-+      || (flags&0x0F)==SQLITE_SYNC_FULL
-+  );
- 
--  OSTRACE(("UNFETCH pid=%lu, pFile=%p, offset=%lld, p=%p\n",
--           osGetCurrentProcessId(), pFd, iOff, p));
-+  /* 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( 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 can be omitted - potentially improving
--    ** performance.  */
--    winUnmapfile(pFd);
--  }
-+  OSTRACE(("SYNC file=%p, flags=%x, lock=%d\n",
-+           pFile->h, flags, pFile->locktype));
- 
--  assert( pFd->nFetchOut>=0 );
-+#ifndef SQLITE_TEST
-+  UNUSED_PARAMETER(flags);
-+#else
-+  if( (flags&0x0F)==SQLITE_SYNC_FULL ){
-+    sqlite3_fullsync_count++;
-+  }
-+  sqlite3_sync_count++;
- #endif
- 
--  OSTRACE(("UNFETCH pid=%lu, pFile=%p, rc=SQLITE_OK\n",
--           osGetCurrentProcessId(), fd));
-+  /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
-+  ** no-op
-+  */
-+#ifdef SQLITE_NO_SYNC
-   return SQLITE_OK;
-+#else
-+  rc = osFlushFileBuffers(pFile->h);
-+  SimulateIOError( rc=FALSE );
-+  if( rc ){
-+    OSTRACE(("SYNC file=%p, rc=SQLITE_OK\n", pFile->h));
-+    return SQLITE_OK;
-+  }else{
-+    pFile->lastErrno = osGetLastError();
-+    OSTRACE(("SYNC file=%p, rc=SQLITE_IOERR_FSYNC\n", pFile->h));
-+    return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno,
-+             "winSync", pFile->zPath);
-+  }
-+#endif
- }
- 
- /*
--** Here ends the implementation of all sqlite3_file methods.
--**
--********************** End sqlite3_file Methods *******************************
--******************************************************************************/
--
--/*
--** This vector defines all the methods that can operate on an
--** sqlite3_file for win32.
-+** Determine the current size of a file in bytes
- */
--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 int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
-+  winFile *pFile = (winFile*)id;
-+  int rc = SQLITE_OK;
- 
--/****************************************************************************
--**************************** sqlite3_vfs methods ****************************
--**
--** This division contains the implementation of methods on the
--** sqlite3_vfs object.
--*/
-+  assert( id!=0 );
-+  assert( pSize!=0 );
-+  SimulateIOError(return SQLITE_IOERR_FSTAT);
-+  OSTRACE(("SIZE file=%p, pSize=%p\n", pFile->h, pSize));
- 
--/*
--** 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 *convertUtf8Filename(const char *zFilename){
--  void *zConverted = 0;
--  if( isNT() ){
--    zConverted = utf8ToUnicode(zFilename);
-+#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);
-+    }
-   }
--#ifdef SQLITE_WIN32_HAS_ANSI
--  else{
--    zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);
-+#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);
-+    }
-   }
- #endif
--  /* caller will handle out of memory */
--  return zConverted;
-+  OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n",
-+           pFile->h, pSize, *pSize, sqlite3ErrName(rc)));
-+  return rc;
- }
- 
- /*
--** Create a temporary file name in zBuf.  zBuf must be big enough to
--** hold at pVfs->mxPathname characters.
-+** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
- */
--static int getTempname(int nBuf, char *zBuf){
--  static char zChars[] =
--    "abcdefghijklmnopqrstuvwxyz"
--    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
--    "0123456789";
--  size_t i, j;
--  int nTempPath;
--  char zTempPath[MAX_PATH+2];
-+#ifndef LOCKFILE_FAIL_IMMEDIATELY
-+# define LOCKFILE_FAIL_IMMEDIATELY 1
-+#endif
- 
--  /* 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 );
-+#ifndef LOCKFILE_EXCLUSIVE_LOCK
-+# define LOCKFILE_EXCLUSIVE_LOCK 2
-+#endif
- 
--  memset(zTempPath, 0, MAX_PATH+2);
-+/*
-+** 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
- 
--  if( sqlite3_temp_directory ){
--    sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
--  }
--#if !SQLITE_OS_WINRT
--  else if( isNT() ){
--    char *zMulti;
--    WCHAR zWidePath[MAX_PATH];
--    osGetTempPathW(MAX_PATH-30, zWidePath);
--    zMulti = unicodeToUtf8(zWidePath);
--    if( zMulti ){
--      sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti);
--      sqlite3_free(zMulti);
--    }else{
--      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
--      return SQLITE_IOERR_NOMEM;
--    }
-+/*
-+** 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 getReadLock(winFile *pFile){
-+  int res;
-+  OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype));
-+  if( isNT() ){
-+#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
-   }
- #ifdef SQLITE_WIN32_HAS_ANSI
-   else{
--    char *zUtf8;
--    char zMbcsPath[MAX_PATH];
--    osGetTempPathA(MAX_PATH-30, zMbcsPath);
--    zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
--    if( zUtf8 ){
--      sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
--      sqlite3_free(zUtf8);
--    }else{
--      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
--      return SQLITE_IOERR_NOMEM;
--    }
-+    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
--#endif
--
--  /* Check that the output buffer is large enough for the temporary file 
--  ** name. If it is not, return SQLITE_ERROR.
--  */
--  nTempPath = sqlite3Strlen30(zTempPath);
--
--  if( (nTempPath + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){
--    OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
--    return SQLITE_ERROR;
--  }
--
--  for(i=nTempPath; i>0 && zTempPath[i-1]=='\\'; i--){}
--  zTempPath[i] = 0;
--
--  sqlite3_snprintf(nBuf-18, zBuf, (nTempPath > 0) ?
--                       "%s\\"SQLITE_TEMP_FILE_PREFIX : SQLITE_TEMP_FILE_PREFIX,
--                   zTempPath);
--  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( res == 0 ){
-+    pFile->lastErrno = osGetLastError();
-+    /* No need to log a failure to lock */
-   }
--  zBuf[j] = 0;
--  zBuf[j+1] = 0;
--
--  OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf));
--  return SQLITE_OK;
-+  OSTRACE(("READ-LOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res)));
-+  return res;
- }
- 
- /*
--** 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.
-+** Undo a readlock
- */
--static int winIsDir(const void *zConverted){
--  DWORD attr;
--  int rc = 0;
-+static int unlockReadLock(winFile *pFile){
-+  int res;
-   DWORD lastErrno;
--
-+  OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype));
-   if( isNT() ){
--    int cnt = 0;
--    WIN32_FILE_ATTRIBUTE_DATA sAttrData;
--    memset(&sAttrData, 0, sizeof(sAttrData));
--    while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
--                             GetFileExInfoStandard,
--                             &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){}
--    if( !rc ){
--      return 0; /* Invalid name? */
--    }
--    attr = sAttrData.dwFileAttributes;
--#if SQLITE_OS_WINCE==0
--  }else{
--    attr = osGetFileAttributesA((char*)zConverted);
-+    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,
-+             "unlockReadLock", pFile->zPath);
-   }
--  return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY);
-+  OSTRACE(("READ-UNLOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res)));
-+  return res;
- }
- 
- /*
--** Open a file.
-+** 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.
- */
--static int winOpen(
--  sqlite3_vfs *pVfs,        /* Not used */
--  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;
--  DWORD dwDesiredAccess;
--  DWORD dwShareMode;
--  DWORD dwCreationDisposition;
--  DWORD dwFlagsAndAttributes = 0;
--#if SQLITE_OS_WINCE
--  int isTemp = 0;
--#endif
-+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;
--  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[MAX_PATH+2];     /* Buffer used to create temp filename */
--
--  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
-+  DWORD lastErrno = NO_ERROR;
- 
--  OSTRACE(("OPEN name=%s, pFile=%p, flags=%x, pOutFlags=%p\n",
--           zUtf8Name, id, flags, pOutFlags));
-+  assert( id!=0 );
-+  OSTRACE(("LOCK file=%p, oldLock=%d(%d), newLock=%d\n",
-+           pFile->h, pFile->locktype, pFile->sharedLockByte, locktype));
- 
--  /* 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.
-+  /* 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.
-   */
--  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 );
-+  if( pFile->locktype>=locktype ){
-+    OSTRACE(("LOCK-HELD file=%p, rc=SQLITE_OK\n", pFile->h));
-+    return SQLITE_OK;
-+  }
- 
--  /* 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
--  );
-+  /* 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 );
- 
--  assert( pFile!=0 );
--  memset(pFile, 0, sizeof(winFile));
--  pFile->h = INVALID_HANDLE_VALUE;
-+  /* 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.
-+      */
-+      OSTRACE(("LOCK-PENDING-FAIL file=%p, count=%d, rc=%s\n",
-+               pFile->h, cnt, sqlite3ErrName(res)));
-+      if( cnt ) sqlite3_win32_sleep(1);
-+    }
-+    gotPendingLock = res;
-+    if( !res ){
-+      lastErrno = osGetLastError();
-+    }
-+  }
- 
--#if SQLITE_OS_WINRT
--  if( !sqlite3_temp_directory ){
--    sqlite3_log(SQLITE_ERROR,
--        "sqlite3_temp_directory variable should be set for WinRT");
-+  /* Acquire a shared lock
-+  */
-+  if( locktype==SHARED_LOCK && res ){
-+    assert( pFile->locktype==NO_LOCK );
-+    res = getReadLock(pFile);
-+    if( res ){
-+      newLocktype = SHARED_LOCK;
-+    }else{
-+      lastErrno = osGetLastError();
-+    }
-   }
--#endif
- 
--  /* If the second argument to this function is NULL, generate a 
--  ** temporary file name to use 
-+  /* Acquire a RESERVED lock
-   */
--  if( !zUtf8Name ){
--    assert(isDelete && !isOpenJournal);
--    memset(zTmpname, 0, MAX_PATH+2);
--    rc = getTempname(MAX_PATH+2, zTmpname);
--    if( rc!=SQLITE_OK ){
--      OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc)));
--      return rc;
-+  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();
-     }
--    zUtf8Name = zTmpname;
-   }
- 
--  /* Database filenames are double-zero terminated if they are not
--  ** URIs with parameters.  Hence, they can always be passed into
--  ** sqlite3_uri_parameter().
-+  /* Acquire a PENDING lock
-   */
--  assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) ||
--        zUtf8Name[strlen(zUtf8Name)+1]==0 );
-+  if( locktype==EXCLUSIVE_LOCK && res ){
-+    newLocktype = PENDING_LOCK;
-+    gotPendingLock = 0;
-+  }
- 
--  /* Convert the filename to the system encoding. */
--  zConverted = convertUtf8Filename(zUtf8Name);
--  if( zConverted==0 ){
--    OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name));
--    return SQLITE_IOERR_NOMEM;
-+  /* Acquire an EXCLUSIVE lock
-+  */
-+  if( locktype==EXCLUSIVE_LOCK && res ){
-+    assert( pFile->locktype>=SHARED_LOCK );
-+    res = unlockReadLock(pFile);
-+    res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0,
-+                      SHARED_SIZE, 0);
-+    if( res ){
-+      newLocktype = EXCLUSIVE_LOCK;
-+    }else{
-+      lastErrno = osGetLastError();
-+      getReadLock(pFile);
-+    }
-   }
- 
--  if( winIsDir(zConverted) ){
--    sqlite3_free(zConverted);
--    OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name));
--    return SQLITE_CANTOPEN_ISDIR;
-+  /* 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( isReadWrite ){
--    dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
-+  /* Update the state of the lock has held in the file descriptor then
-+  ** return the appropriate result code.
-+  */
-+  if( res ){
-+    rc = SQLITE_OK;
-   }else{
--    dwDesiredAccess = GENERIC_READ;
-+    OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n",
-+             pFile->h, locktype, newLocktype));
-+    pFile->lastErrno = lastErrno;
-+    rc = SQLITE_BUSY;
-   }
-+  pFile->locktype = (u8)newLocktype;
-+  OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n",
-+           pFile->h, pFile->locktype, sqlite3ErrName(rc)));
-+  return rc;
-+}
- 
--  /* 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;
-+/*
-+** 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.
-+*/
-+static int winCheckReservedLock(sqlite3_file *id, int *pResOut){
-+  int rc;
-+  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 ){
-+    rc = 1;
-+    OSTRACE(("TEST-WR-LOCK file=%p, rc=%d (local)\n", pFile->h, rc));
-   }else{
--    /* Opens a file, only if it exists. */
--    dwCreationDisposition = OPEN_EXISTING;
-+    rc = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE, 0, 1, 0);
-+    if( rc ){
-+      winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
-+    }
-+    rc = !rc;
-+    OSTRACE(("TEST-WR-LOCK file=%p, rc=%d (remote)\n", pFile->h, rc));
-   }
-+  *pResOut = rc;
-+  OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n",
-+           pFile->h, pResOut, *pResOut));
-+  return SQLITE_OK;
-+}
- 
--  dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
-+/*
-+** 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;
-+*/
-+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 && !getReadLock(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( type>=RESERVED_LOCK ){
-+    winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
-+  }
-+  if( locktype==NO_LOCK && type>=SHARED_LOCK ){
-+    unlockReadLock(pFile);
-+  }
-+  if( type>=PENDING_LOCK ){
-+    winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
-+  }
-+  pFile->locktype = (u8)locktype;
-+  OSTRACE(("UNLOCK file=%p, lock=%d, rc=%s\n",
-+           pFile->h, pFile->locktype, sqlite3ErrName(rc)));
-+  return rc;
-+}
- 
--  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
-+/*
-+** If *pArg is inititially 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.
-+*/
-+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{
--    dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
-+    pFile->ctrlFlags |= mask;
-   }
--  /* 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
-+}
- 
--  if( isNT() ){
--#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 &&
--                              retryIoerr(&cnt, &lastErrno) ){
--               /* Noop */
-+/* Forward declaration */
-+static int getTempname(int nBuf, char *zBuf);
-+
-+/*
-+** 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("win32");
-+      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
-+      return SQLITE_OK;
-     }
--#else
--    while( (h = osCreateFileW((LPCWSTR)zConverted,
--                              dwDesiredAccess,
--                              dwShareMode, NULL,
--                              dwCreationDisposition,
--                              dwFlagsAndAttributes,
--                              NULL))==INVALID_HANDLE_VALUE &&
--                              retryIoerr(&cnt, &lastErrno) ){
--               /* Noop */
-+    case SQLITE_FCNTL_WIN32_AV_RETRY: {
-+      int *a = (int*)pArg;
-+      if( a[0]>0 ){
-+        win32IoerrRetry = a[0];
-+      }else{
-+        a[0] = win32IoerrRetry;
-+      }
-+      if( a[1]>0 ){
-+        win32IoerrRetryDelay = a[1];
-+      }else{
-+        a[1] = win32IoerrRetryDelay;
-+      }
-+      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
-+      return SQLITE_OK;
-     }
--#endif
--  }
--#ifdef SQLITE_WIN32_HAS_ANSI
--  else{
--    while( (h = osCreateFileA((LPCSTR)zConverted,
--                              dwDesiredAccess,
--                              dwShareMode, NULL,
--                              dwCreationDisposition,
--                              dwFlagsAndAttributes,
--                              NULL))==INVALID_HANDLE_VALUE &&
--                              retryIoerr(&cnt, &lastErrno) ){
--               /* Noop */
-+    case SQLITE_FCNTL_TEMPFILENAME: {
-+      char *zTFile = sqlite3MallocZero( pFile->pVfs->mxPathname );
-+      if( zTFile ){
-+        getTempname(pFile->pVfs->mxPathname, zTFile);
-+        *(char**)pArg = zTFile;
-+      }
-+      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
-+      return SQLITE_OK;
-     }
--  }
--#endif
--  logIoerr(cnt);
--
--  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);
--    if( isReadWrite && !isExclusive ){
--      return winOpen(pVfs, zName, id, 
--         ((flags|SQLITE_OPEN_READONLY) &
--                     ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)),
--         pOutFlags);
--    }else{
--      return SQLITE_CANTOPEN_BKPT;
-+#if SQLITE_MAX_MMAP_SIZE>0
-+    case SQLITE_FCNTL_MMAP_SIZE: {
-+      i64 newLimit = *(i64*)pArg;
-+      if( newLimit>sqlite3GlobalConfig.mxMmap ){
-+        newLimit = sqlite3GlobalConfig.mxMmap;
-+      }
-+      *(i64*)pArg = pFile->mmapSizeMax;
-+      if( newLimit>=0 ) pFile->mmapSizeMax = newLimit;
-+      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
-+      return SQLITE_OK;
-     }
-+#endif
-   }
-+  OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h));
-+  return SQLITE_NOTFOUND;
-+}
- 
--  if( pOutFlags ){
--    if( isReadWrite ){
--      *pOutFlags = SQLITE_OPEN_READWRITE;
--    }else{
--      *pOutFlags = SQLITE_OPEN_READONLY;
--    }
--  }
-+/*
-+** 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;
-+}
- 
--  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"));
-+/*
-+** 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);
-+}
- 
--#if SQLITE_OS_WINCE
--  if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
--       && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK
--  ){
--    osCloseHandle(h);
--    sqlite3_free(zConverted);
--    OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc)));
--    return rc;
--  }
--  if( isTemp ){
--    pFile->zDeleteOnClose = zConverted;
--  }else
--#endif
--  {
--    sqlite3_free(zConverted);
--  }
-+/* 
-+** 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.
-+*/
-+SYSTEM_INFO winSysInfo;
- 
--  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
-+#ifndef SQLITE_OMIT_WAL
- 
--  OpenCounter(+1);
--  return rc;
-+/*
-+** 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));
-+}
-+#ifdef SQLITE_DEBUG
-+static int winShmMutexHeld(void) {
-+  return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-+}
-+#endif
- 
- /*
--** Delete the named file.
-+** 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.
- **
--** 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.
- */
--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;
--  void *zConverted;
--  UNUSED_PARAMETER(pVfs);
--  UNUSED_PARAMETER(syncDir);
-+struct winShmNode {
-+  sqlite3_mutex *mutex;      /* Mutex to access this object */
-+  char *zFilename;           /* Name of the file */
-+  winFile hFile;             /* File handle from winOpen */
- 
--  SimulateIOError(return SQLITE_IOERR_DELETE);
--  OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir));
-+  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 */
- 
--  zConverted = convertUtf8Filename(zFilename);
--  if( zConverted==0 ){
--    return SQLITE_IOERR_NOMEM;
--  }
--  if( isNT() ){
--    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;
--      }
--#else
--      attr = osGetFileAttributesW(zConverted);
-+  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
-+  u8 nextShmId;              /* Next available winShm.id value */
- #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 ( !retryIoerr(&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 ( !retryIoerr(&cnt, &lastErrno) ){
--        rc = SQLITE_ERROR; /* No more retries. */
--        break;
--      }
--    } while(1);
--  }
-+};
-+
-+/*
-+** A global array of all winShmNode objects.
-+**
-+** The winShmMutexHeld() must be true while reading or writing this list.
-+*/
-+static winShmNode *winShmNodeList = 0;
-+
-+/*
-+** 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.
-+*/
-+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 */
-+#ifdef SQLITE_DEBUG
-+  u8 id;                     /* Id of this connection with its winShmNode */
- #endif
--  if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){
--    rc = winLogError(SQLITE_IOERR_DELETE, lastErrno,
--             "winDelete", zFilename);
--  }else{
--    logIoerr(cnt);
--  }
--  sqlite3_free(zConverted);
--  OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc)));
--  return rc;
--}
-+};
- 
- /*
--** Check the existence and status of a file.
-+** Constants used for locking
- */
--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 */
-+#define WIN_SHM_BASE   ((22+SQLITE_SHM_NLOCK)*4)        /* first lock byte */
-+#define WIN_SHM_DMS    (WIN_SHM_BASE+SQLITE_SHM_NLOCK)  /* deadman switch */
-+
-+/*
-+** 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 */
- ){
--  DWORD attr;
--  int rc = 0;
--  DWORD lastErrno;
--  void *zConverted;
--  UNUSED_PARAMETER(pVfs);
-+  int rc = 0;           /* Result code form Lock/UnlockFileEx() */
- 
--  SimulateIOError( return SQLITE_IOERR_ACCESS; );
--  OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n",
--           zFilename, flags, pResOut));
-+  /* Access to the winShmNode object is serialized by the caller */
-+  assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 );
- 
--  zConverted = convertUtf8Filename(zFilename);
--  if( zConverted==0 ){
--    OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
--    return SQLITE_IOERR_NOMEM;
--  }
--  if( isNT() ){
--    int cnt = 0;
--    WIN32_FILE_ATTRIBUTE_DATA sAttrData;
--    memset(&sAttrData, 0, sizeof(sAttrData));
--    while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
--                             GetFileExInfoStandard, 
--                             &sAttrData)) && retryIoerr(&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{
--      logIoerr(cnt);
--      if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){
--        winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename);
--        sqlite3_free(zConverted);
--        return SQLITE_IOERR_ACCESS;
--      }else{
--        attr = INVALID_FILE_ATTRIBUTES;
--      }
--    }
--  }
--#ifdef SQLITE_WIN32_HAS_ANSI
--  else{
--    attr = osGetFileAttributesA((char*)zConverted);
-+  OSTRACE(("SHM-LOCK file=%p, lock=%d, offset=%d, size=%d\n",
-+           pFile->hFile.h, lockType, ofst, nByte));
-+
-+  /* 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);
-   }
--#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( rc!= 0 ){
-+    rc = SQLITE_OK;
-+  }else{
-+    pFile->lastErrno =  osGetLastError();
-+    rc = SQLITE_BUSY;
-   }
--  *pResOut = rc;
--  OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n",
--           zFilename, pResOut, *pResOut));
--  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);
- 
- /*
--** 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).
-+** 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 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 ( zPathname[0]=='/' || zPathname[0]=='\\' ){
--    return TRUE;
--  }
--
--  /*
--  ** 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 ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ){
--    return TRUE;
-+static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
-+  winShmNode **pp;
-+  winShmNode *p;
-+  BOOL bRc;
-+  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++){
-+        bRc = osUnmapViewOfFile(p->aRegion[i].pMap);
-+        OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n",
-+                 osGetCurrentProcessId(), i, bRc ? "ok" : "failed"));
-+        bRc = osCloseHandle(p->aRegion[i].hMap);
-+        OSTRACE(("SHM-PURGE-CLOSE pid=%lu, region=%d, rc=%s\n",
-+                 osGetCurrentProcessId(), i, bRc ? "ok" : "failed"));
-+      }
-+      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;
-+    }
-   }
--
--  /*
--  ** 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;
- }
- 
- /*
--** Turn a relative pathname into a full pathname.  Write the full
--** pathname into zOut[].  zOut[] will be at least pVfs->mxPathname
--** bytes in size.
-+** 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 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 */
--){
--  
--#if defined(__CYGWIN__)
--  SimulateIOError( return SQLITE_ERROR );
--  UNUSED_PARAMETER(nFull);
--  assert( pVfs->mxPathname>=MAX_PATH );
--  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[MAX_PATH+1];
--    memset(zOut, 0, MAX_PATH+1);
--    cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut,
--                     MAX_PATH+1);
--    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
--                     sqlite3_data_directory, zOut);
--  }else{
--    cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull);
--  }
--  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\\%s",
--                     sqlite3_data_directory, zRelative);
--  }else{
--    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative);
--  }
--  return SQLITE_OK;
--#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 */
- 
--#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)
--  DWORD nByte;
--  void *zConverted;
--  char *zOut;
-+  assert( pDbFd->pShm==0 );    /* Not previously opened */
- 
--  /* If this path name begins with "/X:", where "X" is any alphabetic
--  ** character, discard the initial "/" from the pathname.
-+  /* Allocate space for the new sqlite3_shm object.  Also speculatively
-+  ** allocate space for a new winShmNode and filename.
-   */
--  if( zRelative[0]=='/' && sqlite3Isalpha(zRelative[1]) && zRelative[2]==':' ){
--    zRelative++;
-+  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); 
- 
--  /* 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.
-+  /* Look to see if there is an existing winShmNode that can be used.
-+  ** If no matching winShmNode currently exists, create a new one.
-   */
--  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.
-+  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.
-     */
--    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
--                     sqlite3_data_directory, zRelative);
--    return SQLITE_OK;
--  }
--  zConverted = convertUtf8Filename(zRelative);
--  if( zConverted==0 ){
--    return SQLITE_IOERR_NOMEM;
-+    if( sqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break;
-   }
--  if( isNT() ){
--    LPWSTR zTemp;
--    nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0);
--    if( nByte==0 ){
--      winLogError(SQLITE_ERROR, osGetLastError(),
--                  "GetFullPathNameW1", zConverted);
--      sqlite3_free(zConverted);
--      return SQLITE_CANTOPEN_FULLPATH;
--    }
--    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 ){
--      winLogError(SQLITE_ERROR, osGetLastError(),
--                  "GetFullPathNameW2", zConverted);
--      sqlite3_free(zConverted);
--      sqlite3_free(zTemp);
--      return SQLITE_CANTOPEN_FULLPATH;
-+  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;
-     }
--    sqlite3_free(zConverted);
--    zOut = unicodeToUtf8(zTemp);
--    sqlite3_free(zTemp);
--  }
--#ifdef SQLITE_WIN32_HAS_ANSI
--  else{
--    char *zTemp;
--    nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0);
--    if( nByte==0 ){
--      winLogError(SQLITE_ERROR, osGetLastError(),
--                  "GetFullPathNameA1", zConverted);
--      sqlite3_free(zConverted);
--      return SQLITE_CANTOPEN_FULLPATH;
-+
-+    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;
-     }
--    nByte += 3;
--    zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
--    if( zTemp==0 ){
--      sqlite3_free(zConverted);
--      return SQLITE_IOERR_NOMEM;
-+
-+    /* 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);
-+      }
-     }
--    nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
--    if( nByte==0 ){
--      winLogError(SQLITE_ERROR, osGetLastError(),
--                  "GetFullPathNameA2", zConverted);
--      sqlite3_free(zConverted);
--      sqlite3_free(zTemp);
--      return SQLITE_CANTOPEN_FULLPATH;
-+    if( rc==SQLITE_OK ){
-+      winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
-+      rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1);
-     }
--    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;
-+    if( rc ) goto shm_open_err;
-   }
-+
-+  /* Make the new connection a child of the winShmNode */
-+  p->pShmNode = pShmNode;
-+#ifdef SQLITE_DEBUG
-+  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();
-+  return rc;
- }
- 
--#ifndef SQLITE_OMIT_LOAD_EXTENSION
--/*
--** Interfaces for opening a shared library, finding entry points
--** within the shared library, and closing the shared library.
--*/
- /*
--** Interfaces for opening a shared library, finding entry points
--** within the shared library, and closing the shared library.
-+** Close a connection to shared-memory.  Delete the underlying 
-+** storage if deleteFlag is true.
- */
--static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
--  HANDLE h;
--  void *zConverted = convertUtf8Filename(zFilename);
--  UNUSED_PARAMETER(pVfs);
--  if( zConverted==0 ){
--    return 0;
--  }
--  if( isNT() ){
--#if SQLITE_OS_WINRT
--    h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0);
--#else
--    h = osLoadLibraryW((LPCWSTR)zConverted);
--#endif
--  }
--#ifdef SQLITE_WIN32_HAS_ANSI
--  else{
--    h = osLoadLibraryA((char*)zConverted);
--  }
--#endif
--  sqlite3_free(zConverted);
--  return (void*)h;
--}
--static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
--  UNUSED_PARAMETER(pVfs);
--  getLastErrorMsg(osGetLastError(), nBuf, zBufOut);
--}
--static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){
--  UNUSED_PARAMETER(pVfs);
--  return (void(*)(void))osGetProcAddressA((HANDLE)pH, zSym);
--}
--static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
--  UNUSED_PARAMETER(pVfs);
--  osFreeLibrary((HANDLE)pHandle);
--}
--#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
--  #define winDlOpen  0
--  #define winDlError 0
--  #define winDlSym   0
--  #define winDlClose 0
--#endif
-+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 */
- 
-+  pDbFd = (winFile*)fd;
-+  p = pDbFd->pShm;
-+  if( p==0 ) return SQLITE_OK;
-+  pShmNode = p->pShmNode;
- 
--/*
--** Write up to nBuf bytes of randomness into zBuf.
--*/
--static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
--  int n = 0;
--  UNUSED_PARAMETER(pVfs);
--#if defined(SQLITE_TEST)
--  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);
--  }
--#endif
--  return n;
--}
-+  /* 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;
- 
-+  /* Free the connection p */
-+  sqlite3_free(p);
-+  pDbFd->pShm = 0;
-+  sqlite3_mutex_leave(pShmNode->mutex);
- 
--/*
--** 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;
-+  /* 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();
-+
-+  return SQLITE_OK;
- }
- 
- /*
--** 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.
-+** Change the lock state for a shared-memory segment.
- */
--#ifdef SQLITE_TEST
--SQLITE_API int sqlite3_current_time = 0;  /* Fake system time in seconds since 1970. */
--#endif
-+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 */
- 
--/*
--** 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). 
--  */
--  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;
-+  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 );
- 
--#if SQLITE_OS_WINCE
--  SYSTEMTIME time;
--  osGetSystemTime(&time);
--  /* if SystemTimeToFileTime() fails, it returns zero. */
--  if (!osSystemTimeToFileTime(&time,&ft)){
--    return SQLITE_ERROR;
--  }
--#else
--  osGetSystemTimeAsFileTime( &ft );
--#endif
-+  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 */
- 
--  *piNow = winFiletimeEpoch +
--            ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) + 
--               (sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)10000;
-+    /* 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;
-+    }
- 
--#ifdef SQLITE_TEST
--  if( sqlite3_current_time ){
--    *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
-+    /* Unlock the system-level locks */
-+    if( (mask & allMask)==0 ){
-+      rc = winShmSystemLock(pShmNode, _SHM_UNLCK, ofst+WIN_SHM_BASE, n);
-+    }else{
-+      rc = SQLITE_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" */
-+
-+    /* 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;
-+      }
-+    }
-+
-+    /* 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;
-+      }
-+    }
-+  
-+    /* 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;
-+      }
-+    }
-   }
--#endif
--  UNUSED_PARAMETER(pVfs);
--  return SQLITE_OK;
-+  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;
- }
- 
- /*
--** 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.
-+** 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.
- */
--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 void winShmBarrier(
-+  sqlite3_file *fd          /* Database holding the shared memory */
-+){
-+  UNUSED_PARAMETER(fd);
-+  /* MemoryBarrier(); // does not work -- do not know why not */
-+  winShmEnterMutex();
-+  winShmLeaveMutex();
- }
- 
- /*
--** 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.
-+** 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.
- **
--** 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:
-+** If an error occurs, an error code is returned and *pp is set to NULL.
- **
--**   int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
--**     assert(zBuf[0]=='\0');
--**     return 0;
--**   }
-+** 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.
- **
--** 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.
-+** 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 winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
--  UNUSED_PARAMETER(pVfs);
--  return getLastErrorMsg(osGetLastError(), nBuf, zBuf);
--}
-+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 *p = pDbFd->pShm;
-+  winShmNode *pShmNode;
-+  int rc = SQLITE_OK;
- 
--/*
--** Initialize and deinitialize the operating system interface.
--*/
--SQLITE_API int sqlite3_os_init(void){
--  static sqlite3_vfs winVfs = {
--    3,                   /* iVersion */
--    sizeof(winFile),     /* szOsFile */
--    MAX_PATH,            /* 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( !p ){
-+    rc = winOpenSharedMemory(pDbFd);
-+    if( rc!=SQLITE_OK ) return rc;
-+    p = pDbFd->pShm;
-+  }
-+  pShmNode = p->pShmNode;
- 
--  /* Double-check that the aSyscall[] array has been constructed
--  ** correctly.  See ticket [bb3a86e890c8e96ab] */
--  assert( ArraySize(aSyscall)==74 );
-+  sqlite3_mutex_enter(pShmNode->mutex);
-+  assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
- 
--  /* get memory map allocation granularity */
--  memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
-+  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_realloc(
-+        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
--  osGetNativeSystemInfo(&winSysInfo);
-+      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
--  osGetSystemInfo(&winSysInfo);
-+        pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
-+            0, iOffset - iOffsetShift, szRegion + iOffsetShift
-+        );
- #endif
--  assert( winSysInfo.dwAllocationGranularity>0 );
--  assert( winSysInfo.dwPageSize>0 );
-+        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;
-+      }
- 
--  sqlite3_vfs_register(&winVfs, 1);
--  return SQLITE_OK; 
--}
-+      pShmNode->aRegion[pShmNode->nRegion].pMap = pMap;
-+      pShmNode->aRegion[pShmNode->nRegion].hMap = hMap;
-+      pShmNode->nRegion++;
-+    }
-+  }
- 
--SQLITE_API int sqlite3_os_end(void){ 
--#if SQLITE_OS_WINRT
--  if( sleepObj!=NULL ){
--    osCloseHandle(sleepObj);
--    sleepObj = NULL;
-+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{
-+    *pp = 0;
-   }
--#endif
--  return SQLITE_OK;
-+  sqlite3_mutex_leave(pShmNode->mutex);
-+  return rc;
- }
- 
--#endif /* SQLITE_OS_WIN */
-+#else
-+# define winShmMap     0
-+# define winShmLock    0
-+# define winShmBarrier 0
-+# define winShmUnmap   0
-+#endif /* #ifndef SQLITE_OMIT_WAL */
- 
--/************** 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.
-+** Cleans up the mapped region of the specified file, if any.
- */
--
--/* Size of the Bitvec structure in bytes. */
--#define BITVEC_SZ        512
--
--/* 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*))
--
--/* 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)
--
--/* 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)
--
--#define BITVEC_NPTR      (BITVEC_USIZE/sizeof(Bitvec *))
--
-+#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,
-+                         "winUnmap1", 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,
-+                         "winUnmap2", pFile->zPath);
-+    }
-+    pFile->hMap = NULL;
-+  }
-+  OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
-+           osGetCurrentProcessId(), pFile));
-+  return SQLITE_OK;
-+}
- 
- /*
--** 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.
-+** 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 iSize>BITVEC_NBIT and iDivisor==0 then Bitvec.u.aHash[] is
--** a hash table that will hold up to BITVEC_MXHASH distinct values.
-+** 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.
- **
--** 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.
-+** 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.
- */
--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;
--};
-+static int winMapfile(winFile *pFd, sqlite3_int64 nByte){
-+  sqlite3_int64 nMap = nByte;
-+  int rc;
- 
--/*
--** 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;
--  }
--  return p;
--}
-+  assert( nMap>=0 || pFd->nFetchOut==0 );
-+  OSTRACE(("MAP-FILE pid=%lu, pFile=%p, size=%lld\n",
-+           osGetCurrentProcessId(), pFd, nByte));
- 
--/*
--** 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( 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( 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;
-+  if( nMap>pFd->mmapSizeMax ){
-+    nMap = pFd->mmapSizeMax;
-+  }
-+  nMap &= ~(sqlite3_int64)(winSysInfo.dwPageSize - 1);
-+ 
-+  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;
-     }
--    return 0;
-+#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,
-+                       "winMapfile", pFd->zPath);
-+      /* Log the error, but continue normal operation using xRead/xWrite */
-+      OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n",
-+               osGetCurrentProcessId(), pFd));
-+      return SQLITE_OK;
-+    }
-+    assert( (nMap % winSysInfo.dwPageSize)==0 );
-+#if SQLITE_OS_WINRT
-+    pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, nMap);
-+#else
-+    assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff );
-+    pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap);
-+#endif
-+    if( pNew==NULL ){
-+      osCloseHandle(pFd->hMap);
-+      pFd->hMap = NULL;
-+      pFd->lastErrno = osGetLastError();
-+      winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
-+                  "winMapfile", pFd->zPath);
-+      OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n",
-+               osGetCurrentProcessId(), pFd));
-+      return SQLITE_OK;
-+    }
-+    pFd->pMapRegion = pNew;
-+    pFd->mmapSize = nMap;
-+    pFd->mmapSizeActual = nMap;
-   }
-+
-+  OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
-+           osGetCurrentProcessId(), pFd));
-+  return SQLITE_OK;
- }
-+#endif /* SQLITE_MAX_MMAP_SIZE>0 */
- 
- /*
--** Set the i-th bit.  Return 0 on success and an error code if
--** anything goes wrong.
-+** 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.
- **
--** 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.
-+** 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.
- **
--** 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.
-+** If this function does return a pointer, the caller must eventually 
-+** release the reference by calling winUnfetch().
- */
--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];
--  }
--  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]);
-+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;
-+
-+  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;
-       }
--      sqlite3StackFree(0, aiValues);
--      return rc;
-+    }
-+    if( pFd->mmapSize >= iOff+nAmt ){
-+      *pp = &((u8 *)pFd->pMapRegion)[iOff];
-+      pFd->nFetchOut++;
-     }
-   }
--bitvec_set_end:
--  p->nSet++;
--  p->u.aHash[h] = i;
-+#endif
-+
-+  OSTRACE(("FETCH pid=%lu, pFile=%p, pp=%p, *pp=%p, rc=SQLITE_OK\n",
-+           osGetCurrentProcessId(), fd, pp, *pp));
-   return SQLITE_OK;
- }
- 
- /*
--** Clear the i-th bit.
-+** 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. 
- **
--** pBuf must be a pointer to at least BITVEC_SZ bytes of temporary storage
--** that BitvecClear can use to rebuilt its hash table.
-+** 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_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;
--    }
--  }
--  if( p->iSize<=BITVEC_NBIT ){
--    p->u.aBitmap[i/BITVEC_SZELEM] &= ~(1 << (i&(BITVEC_SZELEM-1)));
-+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{
--    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];
--      }
--    }
-+    /* 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
-+    ** performance.  */
-+    winUnmapfile(pFd);
-   }
-+
-+  assert( pFd->nFetchOut>=0 );
-+#endif
-+
-+  OSTRACE(("UNFETCH pid=%lu, pFile=%p, rc=SQLITE_OK\n",
-+           osGetCurrentProcessId(), fd));
-+  return SQLITE_OK;
- }
- 
- /*
--** 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(p);
--}
-+** Here ends the implementation of all sqlite3_file methods.
-+**
-+********************** End sqlite3_file Methods *******************************
-+******************************************************************************/
- 
- /*
--** Return the value of the iSize parameter specified when Bitvec *p
--** was created.
-+** 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.
- */
--SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec *p){
--  return p->iSize;
--}
- 
--#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.
-+** 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.
- */
--#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
-+static void *convertUtf8Filename(const char *zFilename){
-+  void *zConverted = 0;
-+  if( isNT() ){
-+    zConverted = utf8ToUnicode(zFilename);
-+  }
-+#ifdef SQLITE_WIN32_HAS_ANSI
-+  else{
-+    zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);
-+  }
-+#endif
-+  /* caller will handle out of memory */
-+  return zConverted;
-+}
- 
- /*
--** 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.
--**
--** If a memory allocation error occurs, return -1.
-+** Create a temporary file name in zBuf.  zBuf must be big enough to
-+** hold at pVfs->mxPathname characters.
- */
--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;
-+static int getTempname(int nBuf, char *zBuf){
-+  static char zChars[] =
-+    "abcdefghijklmnopqrstuvwxyz"
-+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-+    "0123456789";
-+  size_t i, j;
-+  int nTempPath;
-+  char zTempPath[MAX_PATH+2];
- 
--  /* 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_malloc(BITVEC_SZ);
--  if( pBitvec==0 || pV==0 || pTmpSpace==0  ) goto bitvec_end;
-+  /* 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 );
- 
--  /* NULL pBitvec tests */
--  sqlite3BitvecSet(0, 1);
--  sqlite3BitvecClear(0, 1, pTmpSpace);
-+  memset(zTempPath, 0, MAX_PATH+2);
- 
--  /* 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;
--      }
-+  if( sqlite3_temp_directory ){
-+    sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
-+  }
-+#if !SQLITE_OS_WINRT
-+  else if( isNT() ){
-+    char *zMulti;
-+    WCHAR zWidePath[MAX_PATH];
-+    osGetTempPathW(MAX_PATH-30, zWidePath);
-+    zMulti = unicodeToUtf8(zWidePath);
-+    if( zMulti ){
-+      sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti);
-+      sqlite3_free(zMulti);
-+    }else{
-+      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
-+      return SQLITE_IOERR_NOMEM;
-     }
--    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;
--      }
-+  }
-+#ifdef SQLITE_WIN32_HAS_ANSI
-+  else{
-+    char *zUtf8;
-+    char zMbcsPath[MAX_PATH];
-+    osGetTempPathA(MAX_PATH-30, zMbcsPath);
-+    zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
-+    if( zUtf8 ){
-+      sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
-+      sqlite3_free(zUtf8);
-     }else{
--      CLEARBIT(pV, (i+1));
--      sqlite3BitvecClear(pBitvec, i+1, pTmpSpace);
-+      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
-+      return SQLITE_IOERR_NOMEM;
-     }
-   }
-+#endif
-+#endif
- 
--  /* 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.
-+  /* Check that the output buffer is large enough for the temporary file 
-+  ** name. If it is not, return SQLITE_ERROR.
-   */
--  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;
--    }
-+  nTempPath = sqlite3Strlen30(zTempPath);
-+
-+  if( (nTempPath + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){
-+    OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
-+    return SQLITE_ERROR;
-   }
- 
--  /* Free allocated structure */
--bitvec_end:
--  sqlite3_free(pTmpSpace);
--  sqlite3_free(pV);
--  sqlite3BitvecDestroy(pBitvec);
--  return rc;
-+  for(i=nTempPath; i>0 && zTempPath[i-1]=='\\'; i--){}
-+  zTempPath[i] = 0;
-+
-+  sqlite3_snprintf(nBuf-18, zBuf, (nTempPath > 0) ?
-+                       "%s\\"SQLITE_TEMP_FILE_PREFIX : SQLITE_TEMP_FILE_PREFIX,
-+                   zTempPath);
-+  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) ];
-+  }
-+  zBuf[j] = 0;
-+  zBuf[j+1] = 0;
-+
-+  OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf));
-+  return SQLITE_OK;
- }
--#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.
-+** 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 winIsDir(const void *zConverted){
-+  DWORD attr;
-+  int rc = 0;
-+  DWORD lastErrno;
-+
-+  if( isNT() ){
-+    int cnt = 0;
-+    WIN32_FILE_ATTRIBUTE_DATA sAttrData;
-+    memset(&sAttrData, 0, sizeof(sAttrData));
-+    while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
-+                             GetFileExInfoStandard,
-+                             &sAttrData)) && retryIoerr(&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);
-+}
-+
-+/*
-+** Open a file.
- */
-+static int winOpen(
-+  sqlite3_vfs *pVfs,        /* Not used */
-+  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;
-+  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[MAX_PATH+2];     /* Buffer used to create temp filename */
-+
-+  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
-+
-+  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);
- 
--/*
--** 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 */
--  int bPurgeable;                     /* True if pages are on backing store */
--  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 */
--};
-+  /* 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 );
- 
--/*
--** 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
-+  /* 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
-+  );
- 
--/********************************** Linked List Management ********************/
-+  assert( pFile!=0 );
-+  memset(pFile, 0, sizeof(winFile));
-+  pFile->h = INVALID_HANDLE_VALUE;
- 
--#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) );
-+#if SQLITE_OS_WINRT
-+  if( !sqlite3_temp_directory ){
-+    sqlite3_log(SQLITE_ERROR,
-+        "sqlite3_temp_directory variable should be set for WinRT");
-   }
--  return (p==0 || p->nRef || (p->flags&PGHDR_NEED_SYNC)==0);
--}
--#endif /* !NDEBUG && SQLITE_ENABLE_EXPENSIVE_ASSERT */
-+#endif
- 
--/*
--** Remove page pPage from the list of dirty pages.
--*/
--static void pcacheRemoveFromDirtyList(PgHdr *pPage){
--  PCache *p = pPage->pCache;
-+  /* If the second argument to this function is NULL, generate a 
-+  ** temporary file name to use 
-+  */
-+  if( !zUtf8Name ){
-+    assert(isDelete && !isOpenJournal);
-+    memset(zTmpname, 0, MAX_PATH+2);
-+    rc = getTempname(MAX_PATH+2, zTmpname);
-+    if( rc!=SQLITE_OK ){
-+      OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc)));
-+      return rc;
-+    }
-+    zUtf8Name = zTmpname;
-+  }
- 
--  assert( pPage->pDirtyNext || pPage==p->pDirtyTail );
--  assert( pPage->pDirtyPrev || pPage==p->pDirty );
-+  /* 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[strlen(zUtf8Name)+1]==0 );
- 
--  /* 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;
-+  /* Convert the filename to the system encoding. */
-+  zConverted = convertUtf8Filename(zUtf8Name);
-+  if( zConverted==0 ){
-+    OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name));
-+    return SQLITE_IOERR_NOMEM;
-   }
- 
--  if( pPage->pDirtyNext ){
--    pPage->pDirtyNext->pDirtyPrev = pPage->pDirtyPrev;
--  }else{
--    assert( pPage==p->pDirtyTail );
--    p->pDirtyTail = pPage->pDirtyPrev;
-+  if( winIsDir(zConverted) ){
-+    sqlite3_free(zConverted);
-+    OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name));
-+    return SQLITE_CANTOPEN_ISDIR;
-   }
--  if( pPage->pDirtyPrev ){
--    pPage->pDirtyPrev->pDirtyNext = pPage->pDirtyNext;
-+
-+  if( isReadWrite ){
-+    dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
-   }else{
--    assert( pPage==p->pDirty );
--    p->pDirty = pPage->pDirtyNext;
-+    dwDesiredAccess = GENERIC_READ;
-   }
--  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;
-+  /* 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;
-+  }
- 
--  assert( pPage->pDirtyNext==0 && pPage->pDirtyPrev==0 && p->pDirty!=pPage );
-+  dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
- 
--  pPage->pDirtyNext = p->pDirty;
--  if( pPage->pDirtyNext ){
--    assert( pPage->pDirtyNext->pDirtyPrev==0 );
--    pPage->pDirtyNext->pDirtyPrev = pPage;
-+  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;
-   }
--  p->pDirty = pPage;
--  if( !p->pDirtyTail ){
--    p->pDirtyTail = pPage;
-+  /* 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
-+
-+  if( isNT() ){
-+#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 &&
-+                              retryIoerr(&cnt, &lastErrno) ){
-+               /* Noop */
-+    }
-+#else
-+    while( (h = osCreateFileW((LPCWSTR)zConverted,
-+                              dwDesiredAccess,
-+                              dwShareMode, NULL,
-+                              dwCreationDisposition,
-+                              dwFlagsAndAttributes,
-+                              NULL))==INVALID_HANDLE_VALUE &&
-+                              retryIoerr(&cnt, &lastErrno) ){
-+               /* Noop */
-+    }
-+#endif
-   }
--  if( !p->pSynced && 0==(pPage->flags&PGHDR_NEED_SYNC) ){
--    p->pSynced = pPage;
-+#ifdef SQLITE_WIN32_HAS_ANSI
-+  else{
-+    while( (h = osCreateFileA((LPCSTR)zConverted,
-+                              dwDesiredAccess,
-+                              dwShareMode, NULL,
-+                              dwCreationDisposition,
-+                              dwFlagsAndAttributes,
-+                              NULL))==INVALID_HANDLE_VALUE &&
-+                              retryIoerr(&cnt, &lastErrno) ){
-+               /* Noop */
-+    }
-   }
--  expensive_assert( pcacheCheckSynced(p) );
--}
-+#endif
-+  logIoerr(cnt);
- 
--/*
--** 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){
--  PCache *pCache = p->pCache;
--  if( pCache->bPurgeable ){
--    if( p->pgno==1 ){
--      pCache->pPage1 = 0;
-+  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);
-+    if( isReadWrite && !isExclusive ){
-+      return winOpen(pVfs, zName, id, 
-+         ((flags|SQLITE_OPEN_READONLY) &
-+                     ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)),
-+         pOutFlags);
-+    }else{
-+      return SQLITE_CANTOPEN_BKPT;
-     }
--    sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, p->pPage, 0);
-   }
--}
- 
--/*************************************************** 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);
-+  if( pOutFlags ){
-+    if( isReadWrite ){
-+      *pOutFlags = SQLITE_OPEN_READWRITE;
-+    }else{
-+      *pOutFlags = SQLITE_OPEN_READONLY;
-+    }
-   }
--}
--
--/*
--** 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().
--*/
--SQLITE_PRIVATE void 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 = szPage;
--  p->szExtra = szExtra;
--  p->bPurgeable = bPurgeable;
--  p->xStress = xStress;
--  p->pStress = pStress;
--  p->szCache = 100;
--}
-+  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"));
- 
--/*
--** 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){
--  assert( pCache->nRef==0 && pCache->pDirty==0 );
--  if( pCache->pCache ){
--    sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
--    pCache->pCache = 0;
--    pCache->pPage1 = 0;
-+#if SQLITE_OS_WINCE
-+  if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
-+       && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK
-+  ){
-+    osCloseHandle(h);
-+    sqlite3_free(zConverted);
-+    OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc)));
-+    return rc;
-+  }
-+  if( isTemp ){
-+    pFile->zDeleteOnClose = zConverted;
-+  }else
-+#endif
-+  {
-+    sqlite3_free(zConverted);
-   }
--  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));
-+  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
-+
-+  OpenCounter(+1);
-+  return rc;
- }
- 
- /*
--** Try to obtain a page from the cache.
-+** Delete the named file.
-+**
-+** 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 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 */
-+static int winDelete(
-+  sqlite3_vfs *pVfs,          /* Not used on win32 */
-+  const char *zFilename,      /* Name of file to delete */
-+  int syncDir                 /* Not used on win32 */
- ){
--  sqlite3_pcache_page *pPage = 0;
--  PgHdr *pPgHdr = 0;
--  int eCreate;
--
--  assert( pCache!=0 );
--  assert( createFlag==1 || createFlag==0 );
--  assert( pgno>0 );
-+  int cnt = 0;
-+  int rc;
-+  DWORD attr;
-+  DWORD lastErrno;
-+  void *zConverted;
-+  UNUSED_PARAMETER(pVfs);
-+  UNUSED_PARAMETER(syncDir);
- 
--  /* If the pluggable cache (sqlite3_pcache*) has not been allocated,
--  ** allocate it now.
--  */
--  if( !pCache->pCache && createFlag ){
--    sqlite3_pcache *p;
--    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;
--  }
-+  SimulateIOError(return SQLITE_IOERR_DELETE);
-+  OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir));
- 
--  eCreate = createFlag * (1 + (!pCache->bPurgeable || !pCache->pDirty));
--  if( pCache->pCache ){
--    pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate);
-+  zConverted = convertUtf8Filename(zFilename);
-+  if( zConverted==0 ){
-+    return SQLITE_IOERR_NOMEM;
-   }
--
--  if( !pPage && eCreate==1 ){
--    PgHdr *pPg;
--
--    /* 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;
--#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));
-+  if( isNT() ){
-+    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;
-+      }
-+#else
-+      attr = osGetFileAttributesW(zConverted);
- #endif
--      rc = pCache->xStress(pCache->pStress, pPg);
--      if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
--        return rc;
-+      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;
-       }
--    }
--
--    pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2);
-+      if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
-+        rc = SQLITE_ERROR; /* Files only. */
-+        break;
-+      }
-+      if ( osDeleteFileW(zConverted) ){
-+        rc = SQLITE_OK; /* Deleted OK. */
-+        break;
-+      }
-+      if ( !retryIoerr(&cnt, &lastErrno) ){
-+        rc = SQLITE_ERROR; /* No more retries. */
-+        break;
-+      }
-+    } while(1);
-   }
--
--  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;
--    }
-+#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 ( !retryIoerr(&cnt, &lastErrno) ){
-+        rc = SQLITE_ERROR; /* No more retries. */
-+        break;
-+      }
-+    } while(1);
-   }
--  *ppPage = pPgHdr;
--  return (pPgHdr==0 && eCreate) ? SQLITE_NOMEM : SQLITE_OK;
-+#endif
-+  if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){
-+    rc = winLogError(SQLITE_IOERR_DELETE, lastErrno,
-+             "winDelete", zFilename);
-+  }else{
-+    logIoerr(cnt);
-+  }
-+  sqlite3_free(zConverted);
-+  OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc)));
-+  return rc;
- }
- 
- /*
--** 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.
-+** Check the existence and status of a file.
- */
--SQLITE_PRIVATE void sqlite3PcacheRelease(PgHdr *p){
--  assert( p->nRef>0 );
--  p->nRef--;
--  if( p->nRef==0 ){
--    PCache *pCache = p->pCache;
--    pCache->nRef--;
--    if( (p->flags&PGHDR_DIRTY)==0 ){
--      pcacheUnpin(p);
-+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;
-+  void *zConverted;
-+  UNUSED_PARAMETER(pVfs);
-+
-+  SimulateIOError( return SQLITE_IOERR_ACCESS; );
-+  OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n",
-+           zFilename, flags, pResOut));
-+
-+  zConverted = convertUtf8Filename(zFilename);
-+  if( zConverted==0 ){
-+    OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
-+    return SQLITE_IOERR_NOMEM;
-+  }
-+  if( isNT() ){
-+    int cnt = 0;
-+    WIN32_FILE_ATTRIBUTE_DATA sAttrData;
-+    memset(&sAttrData, 0, sizeof(sAttrData));
-+    while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
-+                             GetFileExInfoStandard, 
-+                             &sAttrData)) && retryIoerr(&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{
--      /* Move the page to the head of the dirty list. */
--      pcacheRemoveFromDirtyList(p);
--      pcacheAddToDirtyList(p);
-+      logIoerr(cnt);
-+      if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){
-+        winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename);
-+        sqlite3_free(zConverted);
-+        return SQLITE_IOERR_ACCESS;
-+      }else{
-+        attr = INVALID_FILE_ATTRIBUTES;
-+      }
-     }
-   }
--}
--
--/*
--** 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.
--*/
--SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){
--  PCache *pCache;
--  assert( p->nRef==1 );
--  if( p->flags&PGHDR_DIRTY ){
--    pcacheRemoveFromDirtyList(p);
-+#ifdef SQLITE_WIN32_HAS_ANSI
-+  else{
-+    attr = osGetFileAttributesA((char*)zConverted);
-   }
--  pCache = p->pCache;
--  pCache->nRef--;
--  if( p->pgno==1 ){
--    pCache->pPage1 = 0;
-+#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");
-   }
--  sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, p->pPage, 1);
-+  *pResOut = rc;
-+  OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n",
-+           zFilename, pResOut, *pResOut));
-+  return SQLITE_OK;
- }
- 
-+
- /*
--** Make sure the page is marked as dirty. If it isn't dirty already,
--** make it so.
-+** 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 void sqlite3PcacheMakeDirty(PgHdr *p){
--  p->flags &= ~PGHDR_DONT_WRITE;
--  assert( p->nRef>0 );
--  if( 0==(p->flags & PGHDR_DIRTY) ){
--    p->flags |= PGHDR_DIRTY;
--    pcacheAddToDirtyList( p);
-+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 ( zPathname[0]=='/' || zPathname[0]=='\\' ){
-+    return TRUE;
-   }
--}
- 
--/*
--** 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) ){
--    pcacheRemoveFromDirtyList(p);
--    p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC);
--    if( p->nRef==0 ){
--      pcacheUnpin(p);
--    }
-+  /*
-+  ** 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 ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ){
-+    return TRUE;
-   }
-+
-+  /*
-+  ** 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;
- }
- 
- /*
--** Make every page in the cache clean.
-+** 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 void sqlite3PcacheCleanAll(PCache *pCache){
--  PgHdr *p;
--  while( (p = pCache->pDirty)!=0 ){
--    sqlite3PcacheMakeClean(p);
-+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 */
-+){
-+  
-+#if defined(__CYGWIN__)
-+  SimulateIOError( return SQLITE_ERROR );
-+  UNUSED_PARAMETER(nFull);
-+  assert( pVfs->mxPathname>=MAX_PATH );
-+  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[MAX_PATH+1];
-+    memset(zOut, 0, MAX_PATH+1);
-+    cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut,
-+                     MAX_PATH+1);
-+    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
-+                     sqlite3_data_directory, zOut);
-+  }else{
-+    cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull);
-   }
--}
-+  return SQLITE_OK;
-+#endif
- 
--/*
--** 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;
-+#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\\%s",
-+                     sqlite3_data_directory, zRelative);
-+  }else{
-+    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative);
-   }
--  pCache->pSynced = pCache->pDirtyTail;
--}
-+  return SQLITE_OK;
-+#endif
- 
--/*
--** 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) ){
--    pcacheRemoveFromDirtyList(p);
--    pcacheAddToDirtyList(p);
-+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)
-+  DWORD nByte;
-+  void *zConverted;
-+  char *zOut;
-+
-+  /* If this path name begins with "/X:", where "X" is any alphabetic
-+  ** character, discard the initial "/" from the pathname.
-+  */
-+  if( zRelative[0]=='/' && sqlite3Isalpha(zRelative[1]) && zRelative[2]==':' ){
-+    zRelative++;
-   }
--}
- 
--/*
--** 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.
--*/
--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);
--      }
-+  /* 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\\%s",
-+                     sqlite3_data_directory, zRelative);
-+    return SQLITE_OK;
-+  }
-+  zConverted = convertUtf8Filename(zRelative);
-+  if( zConverted==0 ){
-+    return SQLITE_IOERR_NOMEM;
-+  }
-+  if( isNT() ){
-+    LPWSTR zTemp;
-+    nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0);
-+    if( nByte==0 ){
-+      winLogError(SQLITE_ERROR, osGetLastError(),
-+                  "GetFullPathNameW1", zConverted);
-+      sqlite3_free(zConverted);
-+      return SQLITE_CANTOPEN_FULLPATH;
-     }
--    if( pgno==0 && pCache->pPage1 ){
--      memset(pCache->pPage1->pData, 0, pCache->szPage);
--      pgno = 1;
-+    nByte += 3;
-+    zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
-+    if( zTemp==0 ){
-+      sqlite3_free(zConverted);
-+      return SQLITE_IOERR_NOMEM;
-     }
--    sqlite3GlobalConfig.pcache2.xTruncate(pCache->pCache, pgno+1);
-+    nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
-+    if( nByte==0 ){
-+      winLogError(SQLITE_ERROR, osGetLastError(),
-+                  "GetFullPathNameW2", zConverted);
-+      sqlite3_free(zConverted);
-+      sqlite3_free(zTemp);
-+      return SQLITE_CANTOPEN_FULLPATH;
-+    }
-+    sqlite3_free(zConverted);
-+    zOut = unicodeToUtf8(zTemp);
-+    sqlite3_free(zTemp);
-   }
--}
--
--/*
--** Close a cache.
--*/
--SQLITE_PRIVATE void sqlite3PcacheClose(PCache *pCache){
--  if( pCache->pCache ){
--    sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
-+#ifdef SQLITE_WIN32_HAS_ANSI
-+  else{
-+    char *zTemp;
-+    nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0);
-+    if( nByte==0 ){
-+      winLogError(SQLITE_ERROR, osGetLastError(),
-+                  "GetFullPathNameA1", zConverted);
-+      sqlite3_free(zConverted);
-+      return SQLITE_CANTOPEN_FULLPATH;
-+    }
-+    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 ){
-+      winLogError(SQLITE_ERROR, osGetLastError(),
-+                  "GetFullPathNameA2", zConverted);
-+      sqlite3_free(zConverted);
-+      sqlite3_free(zTemp);
-+      return SQLITE_CANTOPEN_FULLPATH;
-+    }
-+    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
- }
- 
--/* 
--** Discard the contents of the cache.
-+#ifndef SQLITE_OMIT_LOAD_EXTENSION
-+/*
-+** Interfaces for opening a shared library, finding entry points
-+** within the shared library, and closing the shared library.
- */
--SQLITE_PRIVATE void sqlite3PcacheClear(PCache *pCache){
--  sqlite3PcacheTruncate(pCache, 0);
--}
--
- /*
--** Merge two lists of pages connected by pDirty and in pgno order.
--** Do not both fixing the pDirtyPrev pointers.
-+** Interfaces for opening a shared library, finding entry points
-+** within the shared library, and closing the shared library.
- */
--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;
--    }
-+static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
-+  HANDLE h;
-+  void *zConverted = convertUtf8Filename(zFilename);
-+  UNUSED_PARAMETER(pVfs);
-+  if( zConverted==0 ){
-+    return 0;
-   }
--  if( pA ){
--    pTail->pDirty = pA;
--  }else if( pB ){
--    pTail->pDirty = pB;
--  }else{
--    pTail->pDirty = 0;
-+  if( isNT() ){
-+#if SQLITE_OS_WINRT
-+    h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0);
-+#else
-+    h = osLoadLibraryW((LPCWSTR)zConverted);
-+#endif
-   }
--  return result.pDirty;
-+#ifdef SQLITE_WIN32_HAS_ANSI
-+  else{
-+    h = osLoadLibraryA((char*)zConverted);
-+  }
-+#endif
-+  sqlite3_free(zConverted);
-+  return (void*)h;
-+}
-+static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
-+  UNUSED_PARAMETER(pVfs);
-+  getLastErrorMsg(osGetLastError(), nBuf, zBufOut);
-+}
-+static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){
-+  UNUSED_PARAMETER(pVfs);
-+  return (void(*)(void))osGetProcAddressA((HANDLE)pH, zSym);
-+}
-+static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
-+  UNUSED_PARAMETER(pVfs);
-+  osFreeLibrary((HANDLE)pHandle);
- }
-+#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
-+  #define winDlOpen  0
-+  #define winDlError 0
-+  #define winDlSym   0
-+  #define winDlClose 0
-+#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.
--**
--** 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.
-+** Write up to nBuf bytes of randomness into zBuf.
- */
--#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 winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
-+  int n = 0;
-+  UNUSED_PARAMETER(pVfs);
-+#if defined(SQLITE_TEST)
-+  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);
-   }
--  p = a[0];
--  for(i=1; i<N_SORT_BUCKET; i++){
--    p = pcacheMergeDirtyList(p, a[i]);
-+  if( sizeof(DWORD)<=nBuf-n ){
-+    DWORD pid = osGetCurrentProcessId();
-+    memcpy(&zBuf[n], &pid, sizeof(pid));
-+    n += sizeof(pid);
-   }
--  return p;
-+#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);
-+  }
-+#endif
-+  return n;
- }
- 
-+
- /*
--** Return a list of all dirty pages in the cache, sorted by page number.
-+** Sleep for a little while.  Return the amount of time slept.
- */
--SQLITE_PRIVATE PgHdr *sqlite3PcacheDirtyList(PCache *pCache){
--  PgHdr *p;
--  for(p=pCache->pDirty; p; p=p->pDirtyNext){
--    p->pDirty = p->pDirtyNext;
--  }
--  return pcacheSortDirtyList(pCache->pDirty);
-+static int winSleep(sqlite3_vfs *pVfs, int microsec){
-+  sqlite3_win32_sleep((microsec+999)/1000);
-+  UNUSED_PARAMETER(pVfs);
-+  return ((microsec+999)/1000)*1000;
- }
- 
--/* 
--** Return the total number of referenced pages held by the cache.
-+/*
-+** 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.
- */
--SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache *pCache){
--  return pCache->nRef;
--}
-+#ifdef SQLITE_TEST
-+SQLITE_API int sqlite3_current_time = 0;  /* Fake system time in seconds since 1970. */
-+#endif
- 
- /*
--** Return the number of references to the page supplied as an argument.
-+** 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.
- */
--SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr *p){
--  return p->nRef;
--}
-+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;
- 
--/* 
--** 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);
-+#if SQLITE_OS_WINCE
-+  SYSTEMTIME time;
-+  osGetSystemTime(&time);
-+  /* if SystemTimeToFileTime() fails, it returns zero. */
-+  if (!osSystemTimeToFileTime(&time,&ft)){
-+    return SQLITE_ERROR;
-   }
--  return nPage;
--}
-+#else
-+  osGetSystemTimeAsFileTime( &ft );
-+#endif
-+
-+  *piNow = winFiletimeEpoch +
-+            ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) + 
-+               (sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)10000;
- 
- #ifdef SQLITE_TEST
--/*
--** Get the suggested cache-size value.
--*/
--SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *pCache){
--  return numberOfCachePages(pCache);
--}
-+  if( sqlite3_current_time ){
-+    *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
-+  }
- #endif
-+  UNUSED_PARAMETER(pVfs);
-+  return SQLITE_OK;
-+}
- 
- /*
--** Set the suggested cache-size value.
-+** 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 void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){
--  pCache->szCache = mxPage;
--  if( pCache->pCache ){
--    sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache,
--                                           numberOfCachePages(pCache));
-+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;
- }
- 
- /*
--** Free up as much memory as possible from the page 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 void sqlite3PcacheShrink(PCache *pCache){
--  if( pCache->pCache ){
--    sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache);
--  }
-+static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
-+  UNUSED_PARAMETER(pVfs);
-+  return getLastErrorMsg(osGetLastError(), nBuf, zBuf);
- }
- 
--#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.
-+** Initialize and deinitialize the operating system interface.
- */
--SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)){
--  PgHdr *pDirty;
--  for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext){
--    xIter(pDirty);
--  }
-+SQLITE_API int sqlite3_os_init(void){
-+  static sqlite3_vfs winVfs = {
-+    3,                   /* iVersion */
-+    sizeof(winFile),     /* szOsFile */
-+    MAX_PATH,            /* 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 */
-+  };
-+
-+  /* Double-check that the aSyscall[] array has been constructed
-+  ** correctly.  See ticket [bb3a86e890c8e96ab] */
-+  assert( ArraySize(aSyscall)==74 );
-+
-+  /* 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 );
-+
-+  sqlite3_vfs_register(&winVfs, 1);
-+  return SQLITE_OK; 
- }
-+
-+SQLITE_API int 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:
-@@ -36670,1019 +38675,1027 @@
- **    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 overriden, 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 others 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.
--*/
--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 */
--};
--
--/*
--** 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.
-+** 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 PgHdr1 {
--  sqlite3_pcache_page page;
--  unsigned int iKey;             /* Key value (page number) */
--  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 */
--};
- 
--/*
--** 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 */
--};
-+/* Size of the Bitvec structure in bytes. */
-+#define BITVEC_SZ        512
- 
--/*
--** Global data used by this cache.
--*/
--static SQLITE_WSD struct PCacheGlobal {
--  PGroup grp;                    /* The global PGroup for mode (2) */
-+/* 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*))
- 
--  /* 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;
-+/* 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)
- 
--/*
--** 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))
-+/* 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)
- 
--/*
--** Macros to enter and leave the PCache LRU mutex.
--*/
--#define pcache1EnterMutex(X) sqlite3_mutex_enter((X)->mutex)
--#define pcache1LeaveMutex(X) sqlite3_mutex_leave((X)->mutex)
-+#define BITVEC_NPTR      (BITVEC_USIZE/sizeof(Bitvec *))
- 
--/******************************************************************************/
--/******** Page Allocation/SQLITE_CONFIG_PCACHE Related Functions **************/
- 
- /*
--** 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.
-+** A bitmap is an instance of the following structure.
- **
--** This routine is called from sqlite3_initialize() and so it is guaranteed
--** to be serialized already.  There is no need for further mutexing.
-+** 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.
- */
--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;
--  }
--}
-+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;
-+};
- 
- /*
--** 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.
--*/
--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;
--    if( p ){
--      pcache1.pFree = pcache1.pFree->pNext;
--      pcache1.nFreeSlot--;
--      pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
--      assert( pcache1.nFreeSlot>=0 );
--      sqlite3StatusAdd(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);
--      sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
--      sqlite3_mutex_leave(pcache1.mutex);
--    }
--#endif
--    sqlite3MemdebugSetType(p, MEMTYPE_PCACHE);
-+** 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;
-   }
-   return p;
- }
- 
- /*
--** Free an allocated buffer obtained from pcache1Alloc().
-+** 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 int pcache1Free(void *p){
--  int nFreed = 0;
-+SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec *p, u32 i){
-   if( p==0 ) return 0;
--  if( p>=pcache1.pStart && p<pcache1.pEnd ){
--    PgFreeslot *pSlot;
--    sqlite3_mutex_enter(pcache1.mutex);
--    sqlite3StatusAdd(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);
--    sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -nFreed);
--    sqlite3_mutex_leave(pcache1.mutex);
--#endif
--    sqlite3_free(p);
-+  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( 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;
-+    }
-+    return 0;
-   }
--  return nFreed;
- }
- 
--#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
- /*
--** Return the size of a pcache allocation
-+** 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 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;
-+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];
-+  }
-+  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(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 int 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_malloc(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);
-+    }
-   }
- 
--  return (p->apHash ? SQLITE_OK : SQLITE_NOMEM);
-+  /* 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:
- **
--** If pPage is NULL then this routine is a no-op.
-+**    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;
- 
--  if( pPage==0 ) return;
--  pCache = pPage->pCache;
--  pGroup = pCache->pGroup;
--  assert( sqlite3_mutex_held(pGroup->mutex) );
--  if( pPage->pLruNext || pPage==pGroup->pLruTail ){
--    if( pPage->pLruPrev ){
--      pPage->pLruPrev->pLruNext = pPage->pLruNext;
--    }
--    if( pPage->pLruNext ){
--      pPage->pLruNext->pLruPrev = pPage->pLruPrev;
--    }
--    if( pGroup->pLruHead==pPage ){
--      pGroup->pLruHead = pPage->pLruNext;
--    }
--    if( pGroup->pLruTail==pPage ){
--      pGroup->pLruTail = pPage->pLruPrev;
--    }
--    pPage->pLruNext = 0;
--    pPage->pLruPrev = 0;
--    pPage->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 */
-+  int bPurgeable;                     /* True if pages are on backing store */
-+  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 */
-+};
-+
-+/*
-+** 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)
- /*
--** Remove the page supplied as an argument from the hash table 
--** (PCache1.apHash structure) that it is currently stored in.
-+** 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:
- **
--** The PGroup mutex must be held when this function is called.
-+**   expensive_assert( pcacheCheckSynced(pCache) );
- */
--static void pcache1RemoveFromHash(PgHdr1 *pPage){
--  unsigned int h;
--  PCache1 *pCache = pPage->pCache;
--  PgHdr1 **pp;
-+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 */
- 
--  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;
-+/*
-+** Remove page pPage from the list of dirty pages.
-+*/
-+static void pcacheRemoveFromDirtyList(PgHdr *pPage){
-+  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;
-+    }
-+    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;
-+  }
-+  pPage->pDirtyNext = 0;
-+  pPage->pDirtyPrev = 0;
- 
--  pCache->nPage--;
-+  expensive_assert( pcacheCheckSynced(p) );
- }
- 
- /*
--** If there are currently more than nMaxPage pages allocated, try
--** to recycle pages to reduce the number allocated to nMaxPage.
-+** Add page pPage to the head of the dirty list (PCache1.pDirty is set to
-+** pPage).
- */
--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 );
--    pcache1PinPage(p);
--    pcache1RemoveFromHash(p);
--    pcache1FreePage(p);
-+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;
-   }
-+  p->pDirty = pPage;
-+  if( !p->pDirtyTail ){
-+    p->pDirtyTail = pPage;
-+  }
-+  if( !p->pSynced && 0==(pPage->flags&PGHDR_NEED_SYNC) ){
-+    p->pSynced = pPage;
-+  }
-+  expensive_assert( pcacheCheckSynced(p) );
- }
- 
- /*
--** 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.
-+** 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 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;
--        pcache1PinPage(pPage);
--        pcache1FreePage(pPage);
--      }else{
--        pp = &pPage->pNext;
--        TESTONLY( nPage++; )
--      }
-+static void pcacheUnpin(PgHdr *p){
-+  PCache *pCache = p->pCache;
-+  if( pCache->bPurgeable ){
-+    if( p->pgno==1 ){
-+      pCache->pPage1 = 0;
-     }
-+    sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, p->pPage, 0);
-   }
--  assert( pCache->nPage==nPage );
- }
- 
--/******************************************************************************/
--/******** sqlite3_pcache Methods **********************************************/
--
--/*
--** Implementation of the sqlite3_pcache.xInit method.
-+/*************************************************** General Interfaces ******
-+**
-+** Initialize and shutdown the page cache subsystem. Neither of these 
-+** functions are threadsafe.
- */
--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 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();
-   }
--  pcache1.grp.mxPinned = 10;
--  pcache1.isInit = 1;
--  return SQLITE_OK;
-+  return sqlite3GlobalConfig.pcache2.xInit(sqlite3GlobalConfig.pcache2.pArg);
- }
--
--/*
--** 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));
-+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);
-+  }
- }
- 
- /*
--** Implementation of the sqlite3_pcache.xCreate method.
--**
--** Allocate a new cache.
-+** Return the size in bytes of a PCache object.
- */
--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 */
--
--  /*
--  ** The seperateCache 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
--
--  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);
--    if( bPurgeable ){
--      pCache->nMin = 10;
--      pcache1EnterMutex(pGroup);
--      pGroup->nMinPage += pCache->nMin;
--      pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
--      pcache1LeaveMutex(pGroup);
--    }
--  }
--  return (sqlite3_pcache *)pCache;
--}
-+SQLITE_PRIVATE int sqlite3PcacheSize(void){ return sizeof(PCache); }
- 
- /*
--** Implementation of the sqlite3_pcache.xCachesize method. 
--**
--** Configure the cache_size limit for a cache.
-+** 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 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);
--  }
-+SQLITE_PRIVATE void 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 = szPage;
-+  p->szExtra = szExtra;
-+  p->bPurgeable = bPurgeable;
-+  p->xStress = xStress;
-+  p->pStress = pStress;
-+  p->szCache = 100;
- }
- 
- /*
--** Implementation of the sqlite3_pcache.xShrink method. 
--**
--** Free up as much memory as possible.
-+** Change the page size for PCache object. The caller must ensure that there
-+** are no outstanding page references when this function is called.
- */
--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 void sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
-+  assert( pCache->nRef==0 && pCache->pDirty==0 );
-+  if( pCache->pCache ){
-+    sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
-+    pCache->pCache = 0;
-+    pCache->pPage1 = 0;
-   }
-+  pCache->szPage = szPage;
- }
- 
- /*
--** Implementation of the sqlite3_pcache.xPagecount method. 
-+** Compute the number of pages of cache requested.
- */
--static int pcache1Pagecount(sqlite3_pcache *p){
--  int n;
--  PCache1 *pCache = (PCache1*)p;
--  pcache1EnterMutex(pCache->pGroup);
--  n = pCache->nPage;
--  pcache1LeaveMutex(pCache->pGroup);
--  return n;
-+static int numberOfCachePages(PCache *p){
-+  if( p->szCache>=0 ){
-+    return p->szCache;
-+  }else{
-+    return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra));
-+  }
- }
- 
- /*
--** 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.
-+** Try to obtain a page from the cache.
- */
--static sqlite3_pcache_page *pcache1Fetch(
--  sqlite3_pcache *p, 
--  unsigned int iKey, 
--  int createFlag
-+SQLITE_PRIVATE int 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 */
- ){
--  unsigned int nPinned;
--  PCache1 *pCache = (PCache1 *)p;
--  PGroup *pGroup;
--  PgHdr1 *pPage = 0;
-+  sqlite3_pcache_page *pPage = 0;
-+  PgHdr *pPgHdr = 0;
-+  int eCreate;
- 
--  assert( pCache->bPurgeable || createFlag!=1 );
--  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!=0 );
-+  assert( createFlag==1 || createFlag==0 );
-+  assert( pgno>0 );
- 
--  /* 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);
-+  /* If the pluggable cache (sqlite3_pcache*) has not been allocated,
-+  ** allocate it now.
-+  */
-+  if( !pCache->pCache && createFlag ){
-+    sqlite3_pcache *p;
-+    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;
-   }
- 
--  /* Step 2: Abort if no existing page is found and createFlag is 0 */
--  if( pPage || createFlag==0 ){
--    pcache1PinPage(pPage);
--    goto fetch_out;
-+  eCreate = createFlag * (1 + (!pCache->bPurgeable || !pCache->pDirty));
-+  if( pCache->pCache ){
-+    pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate);
-   }
- 
--  /* 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;
-+  if( !pPage && eCreate==1 ){
-+    PgHdr *pPg;
-+
-+    /* 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;
-+#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;
-+      }
-+    }
- 
--  /* 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;
-+    pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2);
-   }
- 
--  if( pCache->nPage>=pCache->nHash && pcache1ResizeHash(pCache) ){
--    goto fetch_out;
--  }
-+  if( pPage ){
-+    pPgHdr = (PgHdr *)pPage->pExtra;
- 
--  /* 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;
--    pcache1RemoveFromHash(pPage);
--    pcache1PinPage(pPage);
--    pOther = pPage->pCache;
-+    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] );
- 
--    /* 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( 0==pPgHdr->nRef ){
-+      pCache->nRef++;
-+    }
-+    pPgHdr->nRef++;
-+    if( pgno==1 ){
-+      pCache->pPage1 = pPgHdr;
-+    }
-+  }
-+  *ppPage = pPgHdr;
-+  return (pPgHdr==0 && eCreate) ? SQLITE_NOMEM : SQLITE_OK;
-+}
- 
--    if( pOther->szPage+pOther->szExtra != pCache->szPage+pCache->szExtra ){
--      pcache1FreePage(pPage);
--      pPage = 0;
-+/*
-+** 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.
-+*/
-+SQLITE_PRIVATE void sqlite3PcacheRelease(PgHdr *p){
-+  assert( p->nRef>0 );
-+  p->nRef--;
-+  if( p->nRef==0 ){
-+    PCache *pCache = p->pCache;
-+    pCache->nRef--;
-+    if( (p->flags&PGHDR_DIRTY)==0 ){
-+      pcacheUnpin(p);
-     }else{
--      pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable);
-+      /* Move the page to the head of the dirty list. */
-+      pcacheRemoveFromDirtyList(p);
-+      pcacheAddToDirtyList(p);
-     }
-   }
-+}
- 
--  /* 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();
-+/*
-+** 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.
-+*/
-+SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){
-+  PCache *pCache;
-+  assert( p->nRef==1 );
-+  if( p->flags&PGHDR_DIRTY ){
-+    pcacheRemoveFromDirtyList(p);
-+  }
-+  pCache = p->pCache;
-+  pCache->nRef--;
-+  if( p->pgno==1 ){
-+    pCache->pPage1 = 0;
-+  }
-+  sqlite3GlobalConfig.pcache2.xUnpin(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;
-+    pcacheAddToDirtyList( p);
-+  }
-+}
-+
-+/*
-+** 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) ){
-+    pcacheRemoveFromDirtyList(p);
-+    p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC);
-+    if( p->nRef==0 ){
-+      pcacheUnpin(p);
-+    }
-   }
-+}
- 
--  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;
--    *(void **)pPage->page.pExtra = 0;
--    pCache->apHash[h] = pPage;
-+/*
-+** Make every page in the cache clean.
-+*/
-+SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache *pCache){
-+  PgHdr *p;
-+  while( (p = pCache->pDirty)!=0 ){
-+    sqlite3PcacheMakeClean(p);
-   }
-+}
- 
--fetch_out:
--  if( pPage && iKey>pCache->iMaxKey ){
--    pCache->iMaxKey = iKey;
-+/*
-+** 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;
-   }
--  pcache1LeaveMutex(pGroup);
--  return &pPage->page;
-+  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) ){
-+    pcacheRemoveFromDirtyList(p);
-+    pcacheAddToDirtyList(p);
-+  }
-+}
- 
- /*
--** 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);
-+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);
-+  }
-+}
- 
--  /* 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 );
-+/*
-+** Close a cache.
-+*/
-+SQLITE_PRIVATE void sqlite3PcacheClose(PCache *pCache){
-+  if( pCache->pCache ){
-+    sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
-+  }
-+}
- 
--  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;
-+/* 
-+** Discard the contents of the cache.
-+*/
-+SQLITE_PRIVATE void sqlite3PcacheClear(PCache *pCache){
-+  sqlite3PcacheTruncate(pCache, 0);
-+}
-+
-+/*
-+** 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{
--      pGroup->pLruTail = pPage;
--      pGroup->pLruHead = pPage;
-+      pTail->pDirty = pB;
-+      pTail = pB;
-+      pB = pB->pDirty;
-     }
--    pCache->nRecyclable++;
-   }
--
--  pcache1LeaveMutex(pCache->pGroup);
-+  if( pA ){
-+    pTail->pDirty = pA;
-+  }else if( pB ){
-+    pTail->pDirty = pB;
-+  }else{
-+    pTail->pDirty = 0;
-+  }
-+  return result.pDirty;
- }
- 
- /*
--** Implementation of the sqlite3_pcache.xRekey 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.
-+**
-+** 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 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;
-+#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);
-+    }
-   }
--  *pp = pPage->pNext;
-+  p = a[0];
-+  for(i=1; i<N_SORT_BUCKET; i++){
-+    p = pcacheMergeDirtyList(p, a[i]);
-+  }
-+  return p;
-+}
- 
--  h = iNew%pCache->nHash;
--  pPage->iKey = iNew;
--  pPage->pNext = pCache->apHash[h];
--  pCache->apHash[h] = pPage;
--  if( iNew>pCache->iMaxKey ){
--    pCache->iMaxKey = iNew;
-+/*
-+** Return a list of all dirty pages in the cache, sorted by page number.
-+*/
-+SQLITE_PRIVATE PgHdr *sqlite3PcacheDirtyList(PCache *pCache){
-+  PgHdr *p;
-+  for(p=pCache->pDirty; p; p=p->pDirtyNext){
-+    p->pDirty = p->pDirtyNext;
-   }
-+  return pcacheSortDirtyList(pCache->pDirty);
-+}
- 
--  pcache1LeaveMutex(pCache->pGroup);
-+/* 
-+** Return the total number of referenced pages held by the cache.
-+*/
-+SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache *pCache){
-+  return pCache->nRef;
- }
- 
- /*
--** Implementation of the sqlite3_pcache.xTruncate method. 
--**
--** 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.
-+** Return the number of references to the page supplied as an argument.
- */
--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;
-+SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr *p){
-+  return p->nRef;
-+}
-+
-+/* 
-+** 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);
-   }
--  pcache1LeaveMutex(pCache->pGroup);
-+  return nPage;
- }
- 
-+#ifdef SQLITE_TEST
- /*
--** Implementation of the sqlite3_pcache.xDestroy method. 
--**
--** Destroy a cache allocated using pcache1Create().
-+** Get the suggested cache-size value.
- */
--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 int sqlite3PcacheGetCachesize(PCache *pCache){
-+  return numberOfCachePages(pCache);
- }
-+#endif
- 
- /*
--** This function is called during initialization (sqlite3_initialize()) to
--** install the default pluggable cache module, assuming the user has not
--** already provided an alternative.
-+** Set the suggested cache-size value.
- */
--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 void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){
-+  pCache->szCache = mxPage;
-+  if( pCache->pCache ){
-+    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
--      pcache1PinPage(p);
--      pcache1RemoveFromHash(p);
--      pcache1FreePage(p);
--    }
--    pcache1LeaveMutex(&pcache1.grp);
-+SQLITE_PRIVATE void sqlite3PcacheShrink(PCache *pCache){
-+  if( pCache->pCache ){
-+    sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache);
-   }
--  return nFree;
- }
--#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
- 
--#ifdef SQLITE_TEST
-+#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
- /*
--** This function is used by test procedures to inspect the internal state
--** of the global cache.
-+** 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 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){
--    nRecyclable++;
-+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:
-@@ -37693,3176 +39706,3005 @@
- **
- *************************************************************************
- **
--** 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 overriden, 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 others 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.  (Sometime 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 */
-+};
-+
-+/*
-+** 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) */
-+  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 */
-+};
-+
-+/*
-+** 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 */
-+};
-+
-+/*
-+** Global data used by this cache.
- */
-+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;
- 
-+/*
-+** 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))
- 
- /*
--** Target size for allocation chunks.
-+** Macros to enter and leave the PCache LRU mutex.
- */
--#define ROWSET_ALLOCATION_SIZE 1024
-+#define pcache1EnterMutex(X) sqlite3_mutex_enter((X)->mutex)
-+#define pcache1LeaveMutex(X) sqlite3_mutex_leave((X)->mutex)
-+
-+/******************************************************************************/
-+/******** Page Allocation/SQLITE_CONFIG_PCACHE Related Functions **************/
- 
- /*
--** The number of rowset entries per allocation chunk.
-+** 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_ENTRY_PER_CHUNK  \
--                       ((ROWSET_ALLOCATION_SIZE-8)/sizeof(struct RowSetEntry))
-+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;
-+  }
-+}
- 
- /*
--** Each entry in a RowSet is an instance of the following 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().
- **
--** 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.
-+** Multiple threads can run this routine at the same time.  Global variables
-+** in pcache1 need to be protected via mutex.
- */
--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 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;
-+    if( p ){
-+      pcache1.pFree = pcache1.pFree->pNext;
-+      pcache1.nFreeSlot--;
-+      pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
-+      assert( pcache1.nFreeSlot>=0 );
-+      sqlite3StatusAdd(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);
-+      sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
-+      sqlite3_mutex_leave(pcache1.mutex);
-+    }
-+#endif
-+    sqlite3MemdebugSetType(p, MEMTYPE_PCACHE);
-+  }
-+  return p;
-+}
- 
- /*
--** 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.
-+** Free an allocated buffer obtained from pcache1Alloc().
- */
--struct RowSetChunk {
--  struct RowSetChunk *pNextChunk;        /* Next chunk on list of them all */
--  struct RowSetEntry aEntry[ROWSET_ENTRY_PER_CHUNK]; /* Allocated entries */
--};
-+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);
-+    sqlite3StatusAdd(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);
-+    sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -nFreed);
-+    sqlite3_mutex_leave(pcache1.mutex);
-+#endif
-+    sqlite3_free(p);
-+  }
-+  return nFreed;
-+}
- 
-+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
- /*
--** A RowSet in an instance of the following structure.
--**
--** A typedef of this structure if found in sqliteInt.h.
-+** Return the size of a pcache allocation
- */
--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 */
--  u8 rsFlags;                    /* Various flags */
--  u8 iBatch;                     /* Current insert batch */
--};
-+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;
-+  }
-+}
-+#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
- 
- /*
--** Allowed values for RowSet.rsFlags
-+** Allocate a new page object initially associated with cache pCache.
- */
--#define ROWSET_SORTED  0x01   /* True if RowSet.pEntry is sorted */
--#define ROWSET_NEXT    0x02   /* True if sqlite3RowSetNext() has been called */
-+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;
-+  }
-+#else
-+  pPg = pcache1Alloc(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++;
-+    }
-+    return p;
-+  }
-+  return 0;
-+}
- 
- /*
--** 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.
-+** Free a page object allocated by pcache1AllocPage().
- **
--** 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.
-+** 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().
- */
--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;
-+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--;
-+    }
-+  }
- }
- 
- /*
--** 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.
-+** 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 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;
-+SQLITE_PRIVATE void *sqlite3PageMalloc(int sz){
-+  return pcache1Alloc(sz);
- }
- 
- /*
--** Allocate a new RowSetEntry object that is associated with the
--** given RowSet.  Return a pointer to the new and completely uninitialized
--** objected.
-+** Free an allocated buffer obtained from sqlite3PageMalloc().
-+*/
-+SQLITE_PRIVATE void sqlite3PageFree(void *p){
-+  pcache1Free(p);
-+}
-+
-+
-+/*
-+** Return true if it desirable to avoid allocating a new page cache
-+** entry.
- **
--** In an OOM situation, the RowSet.db->mallocFailed flag is set and this
--** routine returns 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.
-+**
-+** 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 *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 pcache1UnderMemoryPressure(PCache1 *pCache){
-+  if( pcache1.nSlot && (pCache->szPage+pCache->szExtra)<=pcache1.szSlot ){
-+    return pcache1.bUnderPressure;
-+  }else{
-+    return sqlite3HeapNearlyFull();
-   }
--  p->nFresh--;
--  return p->pFresh++;
- }
- 
-+/******************************************************************************/
-+/******** General Implementation Functions ************************************/
-+
- /*
--** Insert a new value into a RowSet.
-+** This function is used to resize the hash table used by the cache passed
-+** as the first argument.
- **
--** The mallocFailed flag of the database connection is set if a
--** memory allocation fails.
-+** The PCache mutex must be held when this function is called.
- */
--SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet *p, i64 rowid){
--  struct RowSetEntry *pEntry;  /* The new entry */
--  struct RowSetEntry *pLast;   /* The last prior entry */
-+static int pcache1ResizeHash(PCache1 *p){
-+  PgHdr1 **apNew;
-+  unsigned int nNew;
-+  unsigned int i;
- 
--  /* This routine is never called after sqlite3RowSetNext() */
--  assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 );
-+  assert( sqlite3_mutex_held(p->pGroup->mutex) );
- 
--  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;
-+  nNew = p->nHash*2;
-+  if( nNew<256 ){
-+    nNew = 256;
-+  }
-+
-+  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;
-+      }
-     }
--    pLast->pRight = pEntry;
--  }else{
--    p->pEntry = pEntry;
-+    sqlite3_free(p->apHash);
-+    p->apHash = apNew;
-+    p->nHash = nNew;
-   }
--  p->pLast = pEntry;
-+
-+  return (p->apHash ? SQLITE_OK : SQLITE_NOMEM);
- }
- 
- /*
--** Merge two lists of RowSetEntry objects.  Remove duplicates.
-+** 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.
- **
--** The input lists are connected via pRight pointers and are 
--** assumed to each already be in sorted order.
-+** The PGroup mutex must be held when this function is called.
-+**
-+** If pPage is NULL then this routine is a no-op.
- */
--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;
-+static void pcache1PinPage(PgHdr1 *pPage){
-+  PCache1 *pCache;
-+  PGroup *pGroup;
- 
--  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( pPage==0 ) return;
-+  pCache = pPage->pCache;
-+  pGroup = pCache->pGroup;
-+  assert( sqlite3_mutex_held(pGroup->mutex) );
-+  if( pPage->pLruNext || pPage==pGroup->pLruTail ){
-+    if( pPage->pLruPrev ){
-+      pPage->pLruPrev->pLruNext = pPage->pLruNext;
-     }
-+    if( pPage->pLruNext ){
-+      pPage->pLruNext->pLruPrev = pPage->pLruPrev;
-+    }
-+    if( pGroup->pLruHead==pPage ){
-+      pGroup->pLruHead = pPage->pLruNext;
-+    }
-+    if( pGroup->pLruTail==pPage ){
-+      pGroup->pLruTail = pPage->pLruPrev;
-+    }
-+    pPage->pLruNext = 0;
-+    pPage->pLruPrev = 0;
-+    pPage->pCache->nRecyclable--;
-   }
--  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];
-+** 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.
-+*/
-+static void pcache1RemoveFromHash(PgHdr1 *pPage){
-+  unsigned int h;
-+  PCache1 *pCache = pPage->pCache;
-+  PgHdr1 **pp;
- 
--  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;
-+  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;
-+
-+  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 );
-+    pcache1PinPage(p);
-+    pcache1RemoveFromHash(p);
-+    pcache1FreePage(p);
-+  }
-+}
- 
- /*
--** 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.
-+** 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 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 */
-+static void pcache1TruncateUnsafe(
-+  PCache1 *pCache,             /* The cache to truncate */
-+  unsigned int iLimit          /* Drop pages with this pgno or larger */
- ){
--  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;
-+  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;
-+        pcache1PinPage(pPage);
-+        pcache1FreePage(pPage);
-+      }else{
-+        pp = &pPage->pNext;
-+        TESTONLY( nPage++; )
-+      }
-+    }
-   }
--  assert( (*ppLast)->pRight==0 );
-+  assert( pCache->nPage==nPage );
- }
- 
-+/******************************************************************************/
-+/******** sqlite3_pcache Methods **********************************************/
- 
- /*
--** 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.
--**
--** 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.
--**
--** Return a pointer to the root of the constructed binary tree.
-+** Implementation of the sqlite3_pcache.xInit method.
- */
--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 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);
-   }
--  p->pLeft = pLeft;
--  *ppList = p->pRight;
--  p->pRight = rowSetNDeepTree(ppList, iDepth-1);
--  return p;
-+  pcache1.grp.mxPinned = 10;
-+  pcache1.isInit = 1;
-+  return SQLITE_OK;
- }
- 
- /*
--** 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.
-+** Implementation of the sqlite3_pcache.xShutdown method.
-+** Note that the static mutex allocated in xInit does 
-+** not need to be freed.
- */
--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;
-+static void pcache1Shutdown(void *NotUsed){
-+  UNUSED_PARAMETER(NotUsed);
-+  assert( pcache1.isInit!=0 );
-+  memset(&pcache1, 0, sizeof(pcache1));
- }
- 
- /*
--** 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.
-+** Implementation of the sqlite3_pcache.xCreate method.
- **
--** This routine should only be called once in the life of a RowSet.
-+** Allocate a new cache.
- */
--static void rowSetToList(RowSet *p){
-+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 */
- 
--  /* This routine is called only once */
--  assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 );
-+  /*
-+  ** The seperateCache 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
- 
--  if( (p->rsFlags & ROWSET_SORTED)==0 ){
--    p->pEntry = rowSetEntrySort(p->pEntry);
--  }
-+  assert( (szPage & (szPage-1))==0 && szPage>=512 && szPage<=65536 );
-+  assert( szExtra < 300 );
- 
--  /* 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);
-+  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);
-+    if( bPurgeable ){
-+      pCache->nMin = 10;
-+      pcache1EnterMutex(pGroup);
-+      pGroup->nMinPage += pCache->nMin;
-+      pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
-+      pcache1LeaveMutex(pGroup);
-     }
--    p->pForest = p->pForest->pRight;
-   }
--#endif
--  p->rsFlags |= ROWSET_NEXT;  /* Verify this routine is never called again */
-+  return (sqlite3_pcache *)pCache;
- }
- 
- /*
--** Extract the smallest element from the RowSet.
--** Write the element into *pRowid.  Return 1 on success.  Return
--** 0 if the RowSet is already empty.
-+** Implementation of the sqlite3_pcache.xCachesize method. 
- **
--** After this routine has been called, the sqlite3RowSetInsert()
--** routine may not be called again.  
-+** Configure the cache_size limit for a cache.
- */
--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);
--
--  /* 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;
-+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);
-   }
- }
- 
- /*
--** Check to see if element iRowid was inserted into the rowset as
--** part of any insert batch prior to iBatch.  Return 1 or 0.
-+** Implementation of the sqlite3_pcache.xShrink method. 
- **
--** 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
--** pRowSet->pForest so that they can be tested.
-+** Free up as much memory as possible.
- */
--SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, u8 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;
-+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);
-   }
-+}
- 
--  /* 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;
-+/*
-+** Implementation of the sqlite3_pcache.xPagecount method. 
-+*/
-+static int pcache1Pagecount(sqlite3_pcache *p){
-+  int n;
-+  PCache1 *pCache = (PCache1*)p;
-+  pcache1EnterMutex(pCache->pGroup);
-+  n = pCache->nPage;
-+  pcache1LeaveMutex(pCache->pGroup);
-+  return n;
- }
- 
--/************** End of rowset.c **********************************************/
--/************** Begin file pager.c *******************************************/
- /*
--** 2001 September 15
-+** Implementation of the sqlite3_pcache.xFetch method. 
- **
--** The author disclaims copyright to this source code.  In place of
--** a legal notice, here is a blessing:
-+** Fetch a page by key value.
- **
--**    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.
-+** 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.
- **
--*************************************************************************
--** 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.
--*/
--#ifndef SQLITE_OMIT_DISKIO
--/************** Include wal.h in the middle of pager.c ***********************/
--/************** Begin file wal.h *********************************************/
--/*
--** 2010 February 1
-+** 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.
- **
--** The author disclaims copyright to this source code.  In place of
--** a legal notice, here is a blessing:
-+** 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).
- **
--**    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.
-+**   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.
- **
--*************************************************************************
--** 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.
-+**   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.
- */
-+static sqlite3_pcache_page *pcache1Fetch(
-+  sqlite3_pcache *p, 
-+  unsigned int iKey, 
-+  int createFlag
-+){
-+  unsigned int nPinned;
-+  PCache1 *pCache = (PCache1 *)p;
-+  PGroup *pGroup;
-+  PgHdr1 *pPage = 0;
- 
--#ifndef _WAL_H_
--#define _WAL_H_
--
--
--/* Additional values that can be added to the sync_flags argument of
--** sqlite3WalFrames():
--*/
--#define WAL_SYNC_TRANSACTIONS  0x20   /* Sync at the end of each transaction */
--#define SQLITE_SYNC_MASK       0x13   /* Mask off the SQLITE_SYNC_* values */
-+  assert( pCache->bPurgeable || createFlag!=1 );
-+  assert( pCache->bPurgeable || pCache->nMin==0 );
-+  assert( pCache->bPurgeable==0 || pCache->nMin==10 );
-+  assert( pCache->nMin==0 || pCache->bPurgeable );
-+  pcache1EnterMutex(pGroup = pCache->pGroup);
- 
--#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
-+  /* 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);
-+  }
- 
--#define WAL_SAVEPOINT_NDATA 4
-+  /* Step 2: Abort if no existing page is found and createFlag is 0 */
-+  if( pPage || createFlag==0 ){
-+    pcache1PinPage(pPage);
-+    goto fetch_out;
-+  }
- 
--/* Connection to a write-ahead log (WAL) file. 
--** There is one object of this type for each pager. 
--*/
--typedef struct Wal Wal;
-+  /* 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
- 
--/* 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 *);
-+  /* 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;
-+  }
- 
--/* Set the limiting size of a WAL file. */
--SQLITE_PRIVATE void sqlite3WalLimit(Wal*, i64);
-+  if( pCache->nPage>=pCache->nHash && pcache1ResizeHash(pCache) ){
-+    goto fetch_out;
-+  }
- 
--/* 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.
--*/
--SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *);
--SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal);
-+  /* 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;
-+    pcache1RemoveFromHash(pPage);
-+    pcache1PinPage(pPage);
-+    pOther = pPage->pCache;
- 
--/* 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 *);
-+    /* 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 the WAL is not empty, return the size of the database. */
--SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal);
-+    if( pOther->szPage+pOther->szExtra != pCache->szPage+pCache->szExtra ){
-+      pcache1FreePage(pPage);
-+      pPage = 0;
-+    }else{
-+      pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable);
-+    }
-+  }
- 
--/* Obtain or release the WRITER lock. */
--SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal);
--SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal);
-+  /* 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();
-+  }
- 
--/* Undo any frames written (but not committed) to the log */
--SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx);
-+  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;
-+    *(void **)pPage->page.pExtra = 0;
-+    pCache->apHash[h] = pPage;
-+  }
- 
--/* Return an integer that records the current (uncommitted) write
--** position in the WAL */
--SQLITE_PRIVATE void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData);
-+fetch_out:
-+  if( pPage && iKey>pCache->iMaxKey ){
-+    pCache->iMaxKey = iKey;
-+  }
-+  pcache1LeaveMutex(pGroup);
-+  return &pPage->page;
-+}
- 
--/* 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);
-+/*
-+** Implementation of the sqlite3_pcache.xUnpin method.
-+**
-+** 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);
- 
--/* 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 */
--);
-+  /* 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 );
- 
--/* 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.
--*/
--SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal);
-+  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++;
-+  }
- 
--/* 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);
-+  pcache1LeaveMutex(pCache->pGroup);
-+}
- 
--/* 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. 
-+/*
-+** Implementation of the sqlite3_pcache.xRekey method. 
- */
--SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal);
-+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 );
- 
--#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
-+  pcache1EnterMutex(pCache->pGroup);
- 
--#endif /* ifndef SQLITE_OMIT_WAL */
--#endif /* _WAL_H_ */
-+  h = iOld%pCache->nHash;
-+  pp = &pCache->apHash[h];
-+  while( (*pp)!=pPage ){
-+    pp = &(*pp)->pNext;
-+  }
-+  *pp = pPage->pNext;
- 
--/************** End of wal.h *************************************************/
--/************** Continuing where we left off in pager.c **********************/
-+  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);
-+}
- 
--/******************* 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 arbitarily without effecting 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
--**     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.
-+/*
-+** Implementation of the sqlite3_pcache.xTruncate method. 
- **
--** (13) A SHARED lock is held on the database file while reading any
--**      content out of the database file.
-+** 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. 
- **
--******************************************************************************/
-+** Destroy a cache allocated using pcache1Create().
-+*/
-+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);
-+}
- 
- /*
--** Macros for troubleshooting.  Normally turned off
-+** This function is called during initialization (sqlite3_initialize()) to
-+** install the default pluggable cache module, assuming the user has not
-+** already provided an alternative.
- */
--#if 0
--int sqlite3PagerTrace=1;  /* True to enable tracing */
--#define sqlite3DebugPrintf printf
--#define PAGERTRACE(X)     if( sqlite3PagerTrace ){ sqlite3DebugPrintf X; }
--#else
--#define PAGERTRACE(X)
--#endif
-+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);
-+}
- 
-+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
- /*
--** The following two macros are used within the PAGERTRACE() macros above
--** to print out file-descriptors. 
-+** 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.
- **
--** 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.
-+** 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.
- */
--#define PAGERID(p) ((int)(p->fd))
--#define FILEHANDLEID(fd) ((int)fd)
-+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
-+      pcache1PinPage(p);
-+      pcache1RemoveFromHash(p);
-+      pcache1FreePage(p);
-+    }
-+    pcache1LeaveMutex(&pcache1.grp);
-+  }
-+  return nFree;
-+}
-+#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
- 
-+#ifdef SQLITE_TEST
- /*
--** 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:
--**
--**    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.
--**
--**    Temporary pager files may enter the ERROR state, but in-memory pagers
--**    cannot.
--**
--**    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.
--**
--**    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.
--**
--**    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().
-+** This function is used by test procedures to inspect the internal state
-+** of the global cache.
-+*/
-+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){
-+    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 ******************************************/
-+/*
-+** 2008 December 3
- **
--**      3. An error occurs while attempting to write to the journal or
--**         database file in function pagerStress() in order to free up
--**         memory.
-+** The author disclaims copyright to this source code.  In place of
-+** a legal notice, here is a blessing:
- **
--**    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.
-+**    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.
- **
--**    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.
--**    
-+** This module implements an object we call a "RowSet".
- **
--** Notes:
-+** 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.
- **
--**   * 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.
-+** 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.
- **
--**   * 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".
-+** Hence, the primitive operations for a RowSet are:
- **
--**   * See also: assert_pager_state().
--*/
--#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
--
--/*
--** 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.
-+**    CREATE
-+**    INSERT
-+**    TEST
-+**    SMALLEST
-+**    DESTROY
- **
--** 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 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 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 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 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
--** 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.
-+** 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.
- **
--** 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.
-+** No INSERTs may occurs after a SMALLEST.  An assertion will fail if
-+** that is attempted.
- **
--** 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.
-+** The cost of an INSERT is roughly constant.  (Sometime 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).
- **
--** Pager.eLock may only be set to UNKNOWN_LOCK when the pager is in 
--** PAGER_OPEN state.
-+** There is an added cost of O(N) when switching between TEST and
-+** SMALLEST primitives.
- */
--#define UNKNOWN_LOCK                (EXCLUSIVE_LOCK+1)
-+
- 
- /*
--** A macro used for invoking the codec if there is one
-+** Target size for allocation chunks.
- */
--#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
-+#define ROWSET_ALLOCATION_SIZE 1024
- 
- /*
--** 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.
-+** The number of rowset entries per allocation chunk.
- */
--#define MAX_SECTOR_SIZE 0x10000
-+#define ROWSET_ENTRY_PER_CHUNK  \
-+                       ((ROWSET_ALLOCATION_SIZE-8)/sizeof(struct RowSetEntry))
- 
- /*
--** 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().
-+** Each entry in a RowSet is an instance of the following object.
- **
--** 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()).
-+** 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.
- */
--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
-+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) */
- };
- 
- /*
--** A 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, doNotSyncSpill
-+** 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.
- **
--**   These two boolean 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).
-+** A typedef of this structure if found in sqliteInt.h.
-+*/
-+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 */
-+  u8 rsFlags;                    /* Various flags */
-+  u8 iBatch;                     /* Current insert batch */
-+};
-+
-+/*
-+** 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 */
-+
-+/*
-+** 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.
- **
--**   When doNotSpill is non-zero, writing to the database from pagerStress()
--**   is disabled altogether. This 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().
-+** It must be the case that N is sufficient to make a Rowset.  If not
-+** an assertion fault occurs.
- ** 
--**   If doNotSyncSpill is non-zero, 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. 
--**
--** subjInMemory
--**
--**   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.
--**
--** dbSize, dbOrigSize, dbFileSize
--**
--**   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). 
--**
--**   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).
--**
--**   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.
--**
--**   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.
--**
--**   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 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.
--**
--** 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
-+** 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;
-+}
-+
-+/*
-+** 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;
-+}
-+
-+/*
-+** Allocate a new RowSetEntry object that is associated with the
-+** given RowSet.  Return a pointer to the new and completely uninitialized
-+** objected.
- **
--**   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.
-+** In an OOM situation, the RowSet.db->mallocFailed flag is set and this
-+** routine returns NULL.
- */
--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 file */
--  u8 readOnly;                /* True for a read-only database */
--  u8 memDb;                   /* True to inhibit all file I/O */
-+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 block contains those class members that change during
--  ** routine opertion.  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 doNotSyncSpill;          /* Do not do a spill that requires jrnl sync */
--  u8 subjInMemory;            /* True to use in-memory sub-journals */
--  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[] */
--  char dbFileVers[16];        /* Changes whenever database file changes */
-+/*
-+** Insert a new value into a RowSet.
-+**
-+** The mallocFailed flag of the database connection is set if a
-+** memory allocation fails.
-+*/
-+SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet *p, i64 rowid){
-+  struct RowSetEntry *pEntry;  /* The new entry */
-+  struct RowSetEntry *pLast;   /* The last prior entry */
- 
--  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) */
--  /*
--  ** End of the routinely-changing class members
--  ***************************************************************************/
-+  /* This routine is never called after sqlite3RowSetNext() */
-+  assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 );
- 
--  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
--};
-+  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;
-+}
- 
- /*
--** 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().
-+** Merge two lists of RowSetEntry objects.  Remove duplicates.
-+**
-+** The input lists are connected via pRight pointers and are 
-+** assumed to each already be in sorted order.
- */
--#define PAGER_STAT_HIT   0
--#define PAGER_STAT_MISS  1
--#define PAGER_STAT_WRITE 2
-+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;
-+    }
-+  }
-+  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 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
-+** 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;
-+}
- 
- 
- /*
--** 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.
-+** 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.
- */
--static const unsigned char aJournalMagic[] = {
--  0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd7,
--};
-+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 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().
-+** 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.
-+**
-+** 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.
-+**
-+** Return a pointer to the root of the constructed binary tree.
- */
--#define JOURNAL_HDR_SZ(pPager) (pPager->sectorSize)
-+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;
-+}
- 
- /*
--** 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.
-+** 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.
- */
--#ifdef SQLITE_OMIT_MEMORYDB
--# define MEMDB 0
--#else
--# define MEMDB pPager->memDb
--#endif
-+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 */
- 
--/*
--** 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
-+  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;
-+}
- 
- /*
--** The maximum legal page number is (2^31 - 1).
-+** 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 routine should only be called once in the life of a RowSet.
- */
--#define PAGER_MAX_PGNO 2147483647
-+static void rowSetToList(RowSet *p){
-+
-+  /* This routine is called only once */
-+  assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 );
-+
-+  if( (p->rsFlags & ROWSET_SORTED)==0 ){
-+    p->pEntry = rowSetEntrySort(p->pEntry);
-+  }
-+
-+  /* 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;
-+  }
-+#endif
-+  p->rsFlags |= ROWSET_NEXT;  /* Verify this routine is never called again */
-+}
- 
- /*
--** 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) ){ ...
--**
--** instead of
-+** Extract the smallest element from the RowSet.
-+** Write the element into *pRowid.  Return 1 on success.  Return
-+** 0 if the RowSet is already empty.
- **
--**   if( pPager->jfd->pMethods ){ ...
-+** After this routine has been called, the sqlite3RowSetInsert()
-+** routine may not be called again.  
- */
--#define isOpen(pFd) ((pFd)->pMethods)
-+SQLITE_PRIVATE int sqlite3RowSetNext(RowSet *p, i64 *pRowid){
-+  assert( p!=0 );
- 
--/*
--** 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);
-+  /* Merge the forest into a single sorted list on first call */
-+  if( (p->rsFlags & ROWSET_NEXT)==0 ) rowSetToList(p);
-+
-+  /* 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;
-+  }
- }
--#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) );
-+** Check to see if element iRowid was inserted into the rowset as
-+** part of any insert batch prior to iBatch.  Return 1 or 0.
- **
--** This function runs many asserts to try to find inconsistencies in
--** the internal state of the Pager object.
-+** 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
-+** pRowSet->pForest so that they can be tested.
- */
--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
--  );
-+SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, u8 iBatch, sqlite3_int64 iRowid){
-+  struct RowSetEntry *p, *pTree;
- 
--  /* 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 );
-+  /* This routine is never called after sqlite3RowSetNext() */
-+  assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 );
- 
--  /* 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.
-+  /* Sort entries into the forest on the first test of a new batch 
-   */
--  assert( p->journalMode==PAGER_JOURNALMODE_OFF || p->useJournal );
--  assert( p->journalMode!=PAGER_JOURNALMODE_OFF || !isOpen(p->jfd) );
-+  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;
-+  }
- 
--  /* 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.
-+  /* Test to see if the iRowid value appears anywhere in the forest.
-+  ** Return 1 if it does and 0 if not.
-   */
--  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 );
-+  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;
-+}
- 
--  /* 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 );
-+/************** End of rowset.c **********************************************/
-+/************** Begin file pager.c *******************************************/
-+/*
-+** 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.
-+*/
-+#ifndef SQLITE_OMIT_DISKIO
-+/************** Include wal.h in the middle of pager.c ***********************/
-+/************** Begin file wal.h *********************************************/
-+/*
-+** 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.
-+*/
- 
--  switch( p->eState ){
--    case PAGER_OPEN:
--      assert( !MEMDB );
--      assert( pPager->errCode==SQLITE_OK );
--      assert( sqlite3PcacheRefCount(pPager->pPCache)==0 || pPager->tempFile );
--      break;
-+#ifndef _WAL_H_
-+#define _WAL_H_
- 
--    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;
-+/* Additional values that can be added to the sync_flags argument of
-+** sqlite3WalFrames():
-+*/
-+#define WAL_SYNC_TRANSACTIONS  0x20   /* Sync at the end of each transaction */
-+#define SQLITE_SYNC_MASK       0x13   /* Mask off the SQLITE_SYNC_* values */
- 
--    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;
-+#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
- 
--    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;
-+#define WAL_SAVEPOINT_NDATA 4
- 
--    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;
-+/* Connection to a write-ahead log (WAL) file. 
-+** There is one object of this type for each pager. 
-+*/
-+typedef struct Wal Wal;
- 
--    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;
--  }
-+/* 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 *);
- 
--  return 1;
--}
--#endif /* ifndef NDEBUG */
-+/* Set the limiting size of a WAL file. */
-+SQLITE_PRIVATE void sqlite3WalLimit(Wal*, i64);
- 
--#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)
-+/* 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 char *print_pager_state(Pager *p){
--  static char zRet[1024];
-+SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *);
-+SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal);
- 
--  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
--  );
-+/* 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 *);
- 
--  return zRet;
--}
--#endif
-+/* If the WAL is not empty, return the size of the database. */
-+SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal);
- 
--/*
--** 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.
-+/* 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.
- */
--static int subjRequiresPage(PgHdr *pPg){
--  Pgno pgno = pPg->pgno;
--  Pager *pPager = pPg->pPager;
--  int i;
--  for(i=0; i<pPager->nSavepoint; i++){
--    PagerSavepoint *p = &pPager->aSavepoint[i];
--    if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){
--      return 1;
--    }
--  }
--  return 0;
--}
-+SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal);
- 
--/*
--** Return true if the page is already in the journal file.
-+/* Tell the wal layer that an EXCLUSIVE lock has been obtained (or released)
-+** by the pager layer on the database file.
- */
--static int pageInJournal(PgHdr *pPg){
--  return sqlite3BitvecTest(pPg->pPager->pInJournal, pPg->pgno);
--}
-+SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op);
- 
--/*
--** 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.
-+/* 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. 
- */
--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;
--}
-+SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal);
- 
--/*
--** Write a 32-bit integer into a string buffer in big-endian byte order.
-+#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).
- */
--#define put32bits(A,B)  sqlite3Put4byte((u8*)A,B)
-+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 arbitarily without effecting 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
-+**     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.
-+**
-+******************************************************************************/
- 
- /*
--** Write a 32-bit integer into the given file descriptor.  Return SQLITE_OK
--** on success or an error code is something goes wrong.
-+** Macros for troubleshooting.  Normally turned off
- */
--static int write32bits(sqlite3_file *fd, i64 offset, u32 val){
--  char ac[4];
--  put32bits(ac, val);
--  return sqlite3OsWrite(fd, ac, 4, offset);
--}
-+#if 0
-+int sqlite3PagerTrace=1;  /* True to enable tracing */
-+#define sqlite3DebugPrintf printf
-+#define PAGERTRACE(X)     if( sqlite3PagerTrace ){ sqlite3DebugPrintf X; }
-+#else
-+#define PAGERTRACE(X)
-+#endif
- 
- /*
--** 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.
-+** The following two macros are used within the PAGERTRACE() macros above
-+** to print out file-descriptors. 
- **
--** 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.
-+** 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.
- */
--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 = sqlite3OsUnlock(pPager->fd, eLock);
--    if( pPager->eLock!=UNKNOWN_LOCK ){
--      pPager->eLock = (u8)eLock;
--    }
--    IOTRACE(("UNLOCK %p %d\n", pPager, eLock))
--  }
--  return rc;
--}
-+#define PAGERID(p) ((int)(p->fd))
-+#define FILEHANDLEID(fd) ((int)fd)
- 
- /*
--** 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. 
-+** 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:
-+**
-+**    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.
-+**
-+**    Temporary pager files may enter the ERROR state, but in-memory pagers
-+**    cannot.
-+**
-+**    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.
-+**
-+**    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.
-+**
-+**    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.
- **
--** 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.
-+**    * 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 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 = 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;
--}
-+#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
- 
- /*
--** This function determines whether or not the atomic-write optimization
--** can be used with this pager. The optimization can be used if:
-+** 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.
- **
--**  (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.
-+** 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 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.
-+** 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.
- **
--** 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.
-+** 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
-+** 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.
-+**
-+** Pager.eLock may only be set to UNKNOWN_LOCK when the pager is in 
-+** PAGER_OPEN state.
- */
--#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 JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager);
--}
--#endif
-+#define UNKNOWN_LOCK                (EXCLUSIVE_LOCK+1)
- 
- /*
--** 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.
-+** A macro used for invoking the codec if there is one
- */
--#ifdef SQLITE_CHECK_PAGES
-+#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
-+
- /*
--** Return a 32-bit hash of the page data for pPage.
-+** 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.
- */
--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);
--}
-+#define MAX_SECTOR_SIZE 0x10000
- 
- /*
--** 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.
-+** 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()).
- */
--#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 */
-+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
-+};
- 
- /*
--** 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.
-+** A open page cache is an instance of struct Pager. A description of
-+** some of the more important member variables follows:
- **
--** 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.
-+** eState
- **
--** 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 current 'state' of the pager object. See the comment and state
-+**   diagram above for a description of the pager state.
- **
--** If it is determined that no master journal file name is present 
--** zMaster[0] is set to 0 and SQLITE_OK returned.
-+** eLock
- **
--** If an error occurs while reading from the journal file, an SQLite
--** error code is returned.
-+**   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, doNotSyncSpill
-+**
-+**   These two boolean 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 doNotSpill is non-zero, writing to the database from pagerStress()
-+**   is disabled altogether. This 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().
-+** 
-+**   If doNotSyncSpill is non-zero, 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. 
-+**
-+** subjInMemory
-+**
-+**   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.
-+**
-+** dbSize, dbOrigSize, dbFileSize
-+**
-+**   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). 
-+**
-+**   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).
-+**
-+**   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.
-+**
-+**   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.
-+**
-+**   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 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.
-+**
-+** 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 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';
-+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 file */
-+  u8 readOnly;                /* True for a read-only database */
-+  u8 memDb;                   /* True to inhibit all file I/O */
- 
--  if( SQLITE_OK!=(rc = sqlite3OsFileSize(pJrnl, &szJ))
--   || szJ<16
--   || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len))
--   || len>=nMaster 
--   || 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;
--  }
-+  /**************************************************************************
-+  ** The following block contains those class members that change during
-+  ** routine opertion.  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 doNotSyncSpill;          /* Do not do a spill that requires jrnl sync */
-+  u8 subjInMemory;            /* True to use in-memory sub-journals */
-+  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[] */
-+  char dbFileVers[16];        /* Changes whenever database file changes */
- 
--  /* 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;
--}
-+  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) */
-+  /*
-+  ** End of the routinely-changing class members
-+  ***************************************************************************/
-+
-+  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
-+};
- 
- /*
--** Return the offset of the sector boundary at or immediately 
--** following the value in pPager->journalOff, assuming a sector 
--** size of pPager->sectorSize bytes.
--**
--** i.e for a sector size of 512:
--**
--**   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;
--}
-+** 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
- 
- /*
--** The journal file must be open when this function is called.
--**
--** 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.
-+** 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.
- */
--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 */
-+#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
- 
--    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.
-+** Journal files begin with the following magic string.  The data
-+** was obtained from /dev/random.  It is used only as a sanity check.
- **
--** 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.
-+** 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 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;
--    }
--  }
-+static const unsigned char aJournalMagic[] = {
-+  0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd7,
-+};
- 
--  pPager->journalHdr = pPager->journalOff = journalHdrOffset(pPager);
-+/*
-+** 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)
- 
--  /* 
--  ** 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 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 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 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
- 
--  /* The page size */
--  put32bits(&zHeader[sizeof(aJournalMagic)+16], pPager->pageSize);
-+/*
-+** 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
- 
--  /* 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));
-+/*
-+** The maximum legal page number is (2^31 - 1).
-+*/
-+#define PAGER_MAX_PGNO 2147483647
- 
--  /* 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;
--  }
-+/*
-+** 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) ){ ...
-+**
-+** instead of
-+**
-+**   if( pPager->jfd->pMethods ){ ...
-+*/
-+#define isOpen(pFd) ((pFd)->pMethods)
- 
--  return rc;
-+/*
-+** 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 
- /*
--** 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.
-+** Usage:
- **
--** 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.
-+**   assert( assert_pager_state(pPager) );
- **
--** 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.
-+** This function runs many asserts to try to find inconsistencies in
-+** the internal state of the Pager object.
- */
--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 */
-+static int assert_pager_state(Pager *p){
-+  Pager *pPager = p;
- 
--  assert( isOpen(pPager->jfd) );      /* Journal file must be open. */
-+  /* 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
-+  );
- 
--  /* 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.
-+  /* 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.
-   */
--  pPager->journalOff = journalHdrOffset(pPager);
--  if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){
--    return SQLITE_DONE;
--  }
--  iHdrOff = pPager->journalOff;
-+  assert( p->tempFile==0 || p->eLock==EXCLUSIVE_LOCK );
-+  assert( p->tempFile==0 || pPager->changeCountDone );
- 
--  /* 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 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.
-   */
--  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;
--    }
--  }
-+  assert( p->journalMode==PAGER_JOURNALMODE_OFF || p->useJournal );
-+  assert( p->journalMode!=PAGER_JOURNALMODE_OFF || !isOpen(p->jfd) );
- 
--  /* 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.
-+  /* 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( 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;
-+  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 );
-   }
- 
--  pPager->journalOff += JOURNAL_HDR_SZ(pPager);
--  return rc;
--}
-+  /* 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;
- 
--/*
--** 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:
--**
--**   + 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 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 */
-+    case PAGER_READER:
-+      assert( pPager->errCode==SQLITE_OK );
-+      assert( p->eLock!=UNKNOWN_LOCK );
-+      assert( p->eLock>=SHARED_LOCK );
-+      break;
- 
--  assert( pPager->setMaster==0 );
--  assert( !pagerUseWal(pPager) );
-+    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;
- 
--  if( !zMaster 
--   || pPager->journalMode==PAGER_JOURNALMODE_MEMORY 
--   || pPager->journalMode==PAGER_JOURNALMODE_OFF 
--  ){
--    return SQLITE_OK;
--  }
--  pPager->setMaster = 1;
--  assert( isOpen(pPager->jfd) );
--  assert( pPager->journalHdr <= pPager->journalOff );
-+    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;
- 
--  /* Calculate the length in bytes and the checksum of zMaster */
--  for(nMaster=0; zMaster[nMaster]; nMaster++){
--    cksum += zMaster[nMaster];
--  }
-+    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;
- 
--  /* 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;
-+    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;
- 
--  /* 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;
-+    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;
-   }
--  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;
-+  return 1;
- }
-+#endif /* ifndef NDEBUG */
- 
-+#ifdef SQLITE_DEBUG 
- /*
--** 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.
-+** 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 PgHdr *pager_lookup(Pager *pPager, Pgno pgno){
--  PgHdr *p;                         /* Return value */
-+static char *print_pager_state(Pager *p){
-+  static char zRet[1024];
- 
--  /* 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;
-+  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
- 
- /*
--** Discard the entire contents of the in-memory page-cache.
-+** 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 void pager_reset(Pager *pPager){
--  sqlite3BackupRestart(pPager->pBackup);
--  sqlite3PcacheClear(pPager->pPCache);
-+static int subjRequiresPage(PgHdr *pPg){
-+  Pgno pgno = pPg->pgno;
-+  Pager *pPager = pPg->pPager;
-+  int i;
-+  for(i=0; i<pPager->nSavepoint; i++){
-+    PagerSavepoint *p = &pPager->aSavepoint[i];
-+    if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){
-+      return 1;
-+    }
-+  }
-+  return 0;
- }
- 
- /*
--** 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.
-+** Return true if the page is already in the journal file.
- */
--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;
-+static int pageInJournal(PgHdr *pPg){
-+  return sqlite3BitvecTest(pPg->pPager->pInJournal, pPg->pgno);
- }
- 
- /*
--** 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.
-+** 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 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 );
--    }
-+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;
- }
- 
- /*
--** 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 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).
--**
--** 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).
-+** Write a 32-bit integer into a string buffer in big-endian byte order.
- */
--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;
--  }
-+#define put32bits(A,B)  sqlite3Put4byte((u8*)A,B)
- 
--  /* 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;
--  }
- 
--  pPager->journalOff = 0;
--  pPager->journalHdr = 0;
--  pPager->setMaster = 0;
-+/*
-+** 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);
- }
- 
- /*
--** 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.
-+** 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.
- **
--** 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).
-+** 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 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;
-+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 = sqlite3OsUnlock(pPager->fd, eLock);
-+    if( pPager->eLock!=UNKNOWN_LOCK ){
-+      pPager->eLock = (u8)eLock;
-+    }
-+    IOTRACE(("UNLOCK %p %d\n", pPager, eLock))
-   }
-   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.
--**
--** Otherwise, any active savepoints are released.
--**
--** 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:
--**
--**   journalMode==MEMORY
--**     Journal file descriptor is simply closed. This destroys an 
--**     in-memory journal.
--**
--**   journalMode==TRUNCATE
--**     Journal file is truncated to zero bytes in size.
--**
--**   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.
--**
--**   journalMode==DELETE
--**     The journal file is closed and deleted using sqlite3OsDelete().
--**
--**     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.
-+** 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. 
- **
--** 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.
-+** 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 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);
--      }
--      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);
--      }
--    }
--  }
-+static int pagerLockDb(Pager *pPager, int eLock){
-+  int rc = SQLITE_OK;
- 
--#ifdef SQLITE_CHECK_PAGES
--  sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash);
--  if( pPager->dbSize==0 && sqlite3PcacheRefCount(pPager->pPCache)>0 ){
--    PgHdr *p = pager_lookup(pPager, 1);
--    if( p ){
--      p->pageHash = 0;
--      sqlite3PagerUnref(p);
-+  assert( eLock==SHARED_LOCK || eLock==RESERVED_LOCK || eLock==EXCLUSIVE_LOCK );
-+  if( pPager->eLock<eLock || pPager->eLock==UNKNOWN_LOCK ){
-+    rc = 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))
-     }
-   }
--#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( !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);
-+  return rc;
- }
- 
- /*
--** Execute a rollback if a transaction is active and unlock the 
--** database file. 
-+** This function determines whether or not the atomic-write optimization
-+** can be used with this pager. The optimization can be used if:
- **
--** 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.
-+**  (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.
- **
--** 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.
-+** 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.
- */
--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);
-+#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;
-     }
-   }
--  pager_unlock(pPager);
-+
-+  return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager);
- }
-+#endif
- 
- /*
--** 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 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.
--**
--** Changing the formula used to compute this checksum results in an
--** incompatible journal file format.
--**
--** 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.
-+** 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.
- */
--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;
-+#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 cksum;
-+  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);
- }
- 
- /*
--** Report the current page size and number of reserved bytes back
--** to the codec.
-+** 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.
- */
--#ifdef SQLITE_HAS_CODEC
--static void pagerReportSize(Pager *pPager){
--  if( pPager->xCodecSizeChng ){
--    pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize,
--                           (int)pPager->nReserve);
--  }
-+#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 pagerReportSize(X)     /* No-op if we do not support a codec */
--#endif
-+#define pager_datahash(X,Y)  0
-+#define pager_pagehash(X)  0
-+#define pager_set_pagehash(X)
-+#define CHECK_PAGE(x)
-+#endif  /* SQLITE_CHECK_PAGES */
- 
- /*
--** 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 main rollback journal uses checksums - the statement journal does 
--** not.
--**
--** 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.
-+** 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 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.
-+** 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 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.
-+** 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.
- **
--** Neither of these two scenarios are possible during a savepoint rollback.
-+** If it is determined that no master journal file name is present 
-+** zMaster[0] is set to 0 and SQLITE_OK returned.
- **
--** 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.
-+** If an error occurs while reading from the journal file, an SQLite
-+** error code is returned.
- */
--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 */
--
--  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;
--    }
--  }
-+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 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 ){
-+  if( SQLITE_OK!=(rc = sqlite3OsFileSize(pJrnl, &szJ))
-+   || szJ<16
-+   || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len))
-+   || len>=nMaster 
-+   || 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;
-   }
- 
--  /* 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 = pager_lookup(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==0 );
--    pPager->doNotSpill++;
--    rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1);
--    assert( pPager->doNotSpill==1 );
--    pPager->doNotSpill--;
--    if( rc!=SQLITE_OK ) return rc;
--    pPg->flags &= ~PGHDR_NEED_READ;
--    sqlite3PcacheMakeDirty(pPg);
-+  /* See if the checksum matches the master journal name */
-+  for(u=0; u<len; u++){
-+    cksum -= zMaster[u];
-   }
--  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().
-+  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.
-     */
--    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);
-+    len = 0;
-   }
--  return rc;
-+  zMaster[len] = '\0';
-+   
-+  return SQLITE_OK;
- }
- 
- /*
--** 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"
--**
--** A master journal file may only be deleted once all of its child 
--** journals have been rolled back.
--**
--** 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 the child journal exists, and if so
--**   * if the child journal contains a reference to master journal 
--**     file zMaster
--**
--** 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().
-+** 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 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.
-+** i.e for a sector size of 512:
- **
--** 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.
-+**   Pager.journalOff          Return value
-+**   ---------------------------------------
-+**   0                         0
-+**   512                       512
-+**   100                       512
-+**   2000                      2048
-+** 
- */
--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[] */
--
--  /* 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;
--
--  /* 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((int)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;
--
--  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;
--      }
--
--      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);
--
--delmaster_out:
--  sqlite3_free(zMasterJournal);
--  if( pMaster ){
--    sqlite3OsClose(pMaster);
--    assert( !isOpen(pJournal) );
--    sqlite3_free(pMaster);
-+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);
-   }
--  return rc;
-+  assert( offset%JOURNAL_HDR_SZ(pPager)==0 );
-+  assert( offset>=c );
-+  assert( (offset-c)<JOURNAL_HDR_SZ(pPager) );
-+  return offset;
- }
- 
--
- /*
--** 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).
-+** The journal file must be open when this function is called.
- **
--** 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.
-+** 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).
- **
--** Or, it might 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 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 successful, return SQLITE_OK. If an IO error occurs while modifying
--** the database file, return the error code to the caller.
-+** 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 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;
-+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);
-       }
-     }
-   }
-@@ -40870,8409 +42712,8969 @@
- }
- 
- /*
--** 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.
-+** 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.
-+**
-+** 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.
- */
--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;
-+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);
-   }
--  return iRet;
--}
- 
--/*
--** 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 
--** 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.
--*/
--static void setSectorSize(Pager *pPager){
--  assert( isOpen(pPager->fd) || pPager->tempFile );
-+  /* 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;
-+    }
-+  }
- 
--  if( pPager->tempFile
--   || (sqlite3OsDeviceCharacteristics(pPager->fd) & 
--              SQLITE_IOCAP_POWERSAFE_OVERWRITE)!=0
-+  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) 
-   ){
--    /* 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;
-+    memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic));
-+    put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff);
-   }else{
--    pPager->sectorSize = sqlite3SectorSize(pPager->fd);
-+    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;
- }
- 
- /*
--** 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.
--**
--** 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 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.
-+** 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.
- **
--** If an I/O or malloc() error occurs, the journal-file is not deleted
--** and an error code is returned.
-+** 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.
- **
--** 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 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 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 */
-+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 */
- 
--  /* Figure out how many records are in the journal.  Abort early if
--  ** the journal is empty.
-+  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.
-   */
--  assert( isOpen(pPager->jfd) );
--  rc = sqlite3OsFileSize(pPager->jfd, &szJ);
--  if( rc!=SQLITE_OK ){
--    goto end_playback;
-+  pPager->journalOff = journalHdrOffset(pPager);
-+  if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){
-+    return SQLITE_DONE;
-   }
-+  iHdrOff = pPager->journalOff;
- 
--  /* 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.
-+  /* 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.
-   */
--  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;
-+  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;
-+    }
-   }
--  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. 
-+  /* 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.
-   */
--  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( 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 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( pPager->journalOff==0 ){
-+    u32 iPageSize;               /* Page-size field of journal header */
-+    u32 iSectorSize;             /* Sector-size field of journal header */
- 
--    /* 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));
-+    /* 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;
-     }
- 
--    /* If this is the first header read from the journal, truncate the
--    ** database file back to its original size.
-+    /* 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( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){
--      rc = pager_truncate(pPager, mxPg);
--      if( rc!=SQLITE_OK ){
--        goto end_playback;
--      }
--      pPager->dbSize = mxPg;
-+    if( iPageSize==0 ){
-+      iPageSize = pPager->pageSize;
-     }
- 
--    /* Copy original pages out of the journal and back into the 
--    ** database file and/or page cache.
-+    /* 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.
-     */
--    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;
-+    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;
-+    }
- 
--  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);
--  }
--  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.
-+    /* 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 = pager_delmaster(pPager, zMaster);
-+    rc = sqlite3PagerSetPagesize(pPager, &iPageSize, -1);
-     testcase( rc!=SQLITE_OK );
--  }
--  if( isHot && nPlayback ){
--    sqlite3_log(SQLITE_NOTICE_RECOVER_ROLLBACK, "recovered %d pages from %s",
--                nPlayback, pPager->zJournal);
-+
-+    /* 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;
-   }
- 
--  /* 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);
-+  pPager->journalOff += JOURNAL_HDR_SZ(pPager);
-   return rc;
- }
- 
- 
- /*
--** 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.
-+** 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 page 1 is read, then the value of Pager.dbFileVers[] is set to
--** the value read from the database file.
-+**   + 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 an IO error occurs, then the IO error is returned to the caller.
--** Otherwise, SQLITE_OK is returned.
-+** 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 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 */
-+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->eState>=PAGER_READER && !MEMDB );
--  assert( isOpen(pPager->fd) );
-+  assert( pPager->setMaster==0 );
-+  assert( !pagerUseWal(pPager) );
- 
--  if( NEVER(!isOpen(pPager->fd)) ){
--    assert( pPager->tempFile );
--    memset(pPg->pData, 0, pPager->pageSize);
-+  if( !zMaster 
-+   || pPager->journalMode==PAGER_JOURNALMODE_MEMORY 
-+   || pPager->journalMode==PAGER_JOURNALMODE_OFF 
-+  ){
-     return SQLITE_OK;
-   }
-+  pPager->setMaster = 1;
-+  assert( isOpen(pPager->jfd) );
-+  assert( pPager->journalHdr <= pPager->journalOff );
- 
--#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;
--    }
-+  /* Calculate the length in bytes and the checksum of zMaster */
-+  for(nMaster=0; zMaster[nMaster]; nMaster++){
-+    cksum += zMaster[nMaster];
-   }
- 
--  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 noising 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));
--    }
-+  /* 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);
-   }
--  CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM);
-+  iHdrOff = pPager->journalOff;
- 
--  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)));
-+  /* 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;
- }
- 
- /*
--** 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.
-+** 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 void pager_write_changecounter(PgHdr *pPg){
--  u32 change_counter;
--
--  /* 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);
-+static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){
-+  PgHdr *p;                         /* Return value */
- 
--  /* 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);
-+  /* 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;
- }
- 
--#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.
--**
--** 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.
-+** Discard the entire contents of the in-memory page-cache.
- */
--static int pagerUndoCallback(void *pCtx, Pgno iPg){
--  int rc = SQLITE_OK;
--  Pager *pPager = (Pager *)pCtx;
--  PgHdr *pPg;
--
--  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);
--      }
--      sqlite3PagerUnref(pPg);
--    }
--  }
--
--  /* 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.
--  */
-+static void pager_reset(Pager *pPager){
-   sqlite3BackupRestart(pPager->pBackup);
--
--  return rc;
-+  sqlite3PcacheClear(pPager->pPCache);
- }
- 
- /*
--** This function is called to rollback a transaction on a WAL database.
-+** 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 int pagerRollbackWal(Pager *pPager){
--  int rc;                         /* Return Code */
--  PgHdr *pList;                   /* List of dirty pages to revert */
--
--  /* 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).
--  */
--  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;
-+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);
-   }
--
--  return rc;
-+  if( !pPager->exclusiveMode || sqlite3IsMemJournal(pPager->sjfd) ){
-+    sqlite3OsClose(pPager->sjfd);
-+  }
-+  sqlite3_free(pPager->aSavepoint);
-+  pPager->aSavepoint = 0;
-+  pPager->nSavepoint = 0;
-+  pPager->nSubRec = 0;
- }
- 
- /*
--** 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 */
--){
--  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 );
--#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( 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 *p;
--    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;
-+** 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 */
- 
--  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 ){
--    PgHdr *p;
--    for(p=pList; p; p=p->pDirty){
--      sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData);
-+  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 );
-     }
-   }
--
--#ifdef SQLITE_CHECK_PAGES
--  pList = sqlite3PcacheDirtyList(pPager->pPCache);
--  for(p=pList; p; p=p->pDirty){
--    pager_set_pagehash(p);
--  }
--#endif
--
-   return rc;
- }
- 
- /*
--** Begin a read transaction on the WAL.
-+** 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.
- **
--** 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.
-+** 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).
-+**
-+** 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 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);
-+static void pager_unlock(Pager *pPager){
- 
--  rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed);
--  if( rc!=SQLITE_OK || changed ){
--    pager_reset(pPager);
--    if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
--  }
-+  assert( pPager->eState==PAGER_READER 
-+       || pPager->eState==PAGER_OPEN 
-+       || pPager->eState==PAGER_ERROR 
-+  );
- 
--  return rc;
--}
--#endif
-+  sqlite3BitvecDestroy(pPager->pInJournal);
-+  pPager->pInJournal = 0;
-+  releaseAllSavepoints(pPager);
- 
--/*
--** 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).
--**
--** 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 pagerPagecount(Pager *pPager, Pgno *pnPage){
--  Pgno nPage;                     /* Value to return via *pnPage */
-+  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;
- 
--  /* 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 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 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;
--      }
-+    /* 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;
-     }
--    nPage = (Pgno)((n+pPager->pageSize-1) / pPager->pageSize);
-+
-+    /* 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 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 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( nPage>pPager->mxPgno ){
--    pPager->mxPgno = (Pgno)nPage;
-+  if( pPager->errCode ){
-+    assert( !MEMDB );
-+    pager_reset(pPager);
-+    pPager->changeCountDone = pPager->tempFile;
-+    pPager->eState = PAGER_OPEN;
-+    pPager->errCode = SQLITE_OK;
-   }
- 
--  *pnPage = nPage;
--  return SQLITE_OK;
--}
--
--#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.
-+  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. 
- **
--** Return SQLITE_OK or an error code.
-+** 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 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.
-+** 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 pagerOpenWalIfPresent(Pager *pPager){
--  int rc = SQLITE_OK;
--  assert( pPager->eState==PAGER_OPEN );
--  assert( pPager->eLock>=SHARED_LOCK );
--
--  if( !pPager->tempFile ){
--    int isWal;                    /* True if WAL file exists */
--    Pgno nPage;                   /* Size of the database file */
--
--    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;
--      }
--    }
-+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;
- }
--#endif
-+
-+static int pager_truncate(Pager *pPager, Pgno nPage);
- 
- /*
--** 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.
-+** 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.
- **
--** 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:
-+** Otherwise, any active savepoints are released.
- **
--**   * 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 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:
- **
--**   * 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.
-+**   journalMode==MEMORY
-+**     Journal file descriptor is simply closed. This destroys an 
-+**     in-memory journal.
- **
--**   * Pages are then played back from the sub-journal file, starting
--**     with the PagerSavepoint.iSubRec and continuing to the end of
--**     the journal file.
-+**   journalMode==TRUNCATE
-+**     Journal file is truncated to zero bytes in size.
- **
--** 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.
-+**   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.
- **
--** 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.
-+**   journalMode==DELETE
-+**     The journal file is closed and deleted using sqlite3OsDelete().
- **
--** 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 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.
- */
--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;
--    }
--  }
-+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 */
- 
--  /* Set the database size back to the value it was before the savepoint 
--  ** being reverted was opened.
-+  /* 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.
-   */
--  pPager->dbSize = pSavepoint ? pSavepoint->nOrig : pPager->dbOrigSize;
--  pPager->changeCountDone = pPager->tempFile;
--
--  if( !pSavepoint && pagerUseWal(pPager) ){
--    return pagerRollbackWal(pPager);
-+  assert( assert_pager_state(pPager) );
-+  assert( pPager->eState!=PAGER_ERROR );
-+  if( pPager->eState<PAGER_WRITER_LOCKED && pPager->eLock<RESERVED_LOCK ){
-+    return SQLITE_OK;
-   }
- 
--  /* 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 );
-+  releaseAllSavepoints(pPager);
-+  assert( isOpen(pPager->jfd) || pPager->pInJournal==0 );
-+  if( isOpen(pPager->jfd) ){
-+    assert( !pagerUseWal(pPager) );
- 
--  /* 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);
-+    /* 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);
-+      }
-+      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);
-+      }
-     }
--    assert( rc!=SQLITE_DONE );
--  }else{
--    pPager->journalOff = 0;
-   }
- 
--  /* 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 );
--
--    /*
--    ** 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( nJRec==0 
--     && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff
--    ){
--      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);
-+#ifdef SQLITE_CHECK_PAGES
-+  sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash);
-+  if( pPager->dbSize==0 && sqlite3PcacheRefCount(pPager->pPCache)>0 ){
-+    PgHdr *p = pager_lookup(pPager, 1);
-+    if( p ){
-+      p->pageHash = 0;
-+      sqlite3PagerUnref(p);
-     }
--    assert( rc!=SQLITE_DONE );
-   }
--  assert( rc!=SQLITE_OK || pPager->journalOff>=szJ );
-+#endif
- 
--  /* 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);
-+  sqlite3BitvecDestroy(pPager->pInJournal);
-+  pPager->pInJournal = 0;
-+  pPager->nRec = 0;
-+  sqlite3PcacheCleanAll(pPager->pPCache);
-+  sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize);
- 
--    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 );
-+  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);
-   }
- 
--  sqlite3BitvecDestroy(pDone);
--  if( rc==SQLITE_OK ){
--    pPager->journalOff = szJ;
-+  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;
--}
--
--/*
--** Change the maximum number of in-memory pages that are allowed.
--*/
--SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){
--  sqlite3PcacheSetCachesize(pPager->pPCache, mxPage);
-+  return (rc==SQLITE_OK?rc2:rc);
- }
- 
- /*
--** Invoke SQLITE_FCNTL_MMAP_SIZE based on the current value of szMmap.
-+** 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.
- */
--static void pagerFixMaplimit(Pager *pPager){
--#if SQLITE_MAX_MMAP_SIZE>0
--  sqlite3_file *fd = pPager->fd;
--  if( isOpen(fd) ){
--    sqlite3_int64 sz;
--    pPager->bUseFetch = (fd->pMethods->iVersion>=3) && pPager->szMmap>0;
--    sz = pPager->szMmap;
--    sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz);
-+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);
-+    }
-   }
--#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);
--}
--
--/*
--** Free as much memory as possible from the pager.
--*/
--SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){
--  sqlite3PcacheShrink(pPager->pPCache);
-+  pager_unlock(pPager);
- }
- 
- /*
--** Adjust the robustness of the database to damage due to OS crashes
--** or power failures by changing the number of syncs()s when writing
--** the rollback journal.  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.
-+** 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.
- **
--** 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.
-+** 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.
- **
--** 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.
-+** Changing the formula used to compute this checksum results in an
-+** incompatible journal file format.
- **
--** Numeric values associated with these states are OFF==1, NORMAL=2,
--** and FULL=3.
-+** 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.
- */
--#ifndef SQLITE_OMIT_PAGER_PRAGMAS
--SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(
--  Pager *pPager,        /* The pager to set safety level for */
--  int level,            /* PRAGMA synchronous.  1=OFF, 2=NORMAL, 3=FULL */  
--  int bFullFsync,       /* PRAGMA fullfsync */
--  int bCkptFullFsync    /* PRAGMA checkpoint_fullfsync */
--){
--  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( bFullFsync ){
--    pPager->syncFlags = SQLITE_SYNC_FULL;
--    pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
--  }else if( bCkptFullFsync ){
--    pPager->syncFlags = SQLITE_SYNC_NORMAL;
--    pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
--  }else{
--    pPager->syncFlags = SQLITE_SYNC_NORMAL;
--    pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL;
--  }
--  pPager->walSyncFlags = pPager->syncFlags;
--  if( pPager->fullSync ){
--    pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS;
-+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;
- }
--#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.  
-+** Report the current page size and number of reserved bytes back
-+** to the codec.
- */
--#ifdef SQLITE_TEST
--SQLITE_API int sqlite3_opentemp_count = 0;
-+#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
  
- /*
--** Open a temporary file.
-+** 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.
- **
--** 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 main rollback journal uses checksums - the statement journal does 
-+** not.
-+**
-+** 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 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.
- **
--** The flags passed to the VFS layer xOpen() call are those specified
--** by parameter vfsFlags ORed with the following:
-+** Neither of these two scenarios are possible during a savepoint rollback.
- **
--**     SQLITE_OPEN_READWRITE
--**     SQLITE_OPEN_CREATE
--**     SQLITE_OPEN_EXCLUSIVE
--**     SQLITE_OPEN_DELETEONCLOSE
-+** 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.
- */
--static int pagerOpentemp(
--  Pager *pPager,        /* The pager object */
--  sqlite3_file *pFile,  /* Write the file descriptor here */
--  int vfsFlags          /* Flags passed through to the VFS */
-+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;               /* Return code */
-+  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 */
- 
--#ifdef SQLITE_TEST
--  sqlite3_opentemp_count++;  /* Used for testing and analysis only */
--#endif
-+  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 */
- 
--  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;
--}
-+  aData = pPager->pTmpSpace;
-+  assert( aData );         /* Temp storage must have already been allocated */
-+  assert( pagerUseWal(pPager)==0 || (!isMainJrnl && isSavepnt) );
- 
--/*
--** Set the busy handler function.
--**
--** 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:
--**
--**   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 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.
--*/
--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;
-+  /* 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 );
- 
--  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);
-+  /* 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 = pager_lookup(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==0 );
-+    pPager->doNotSpill++;
-+    rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1);
-+    assert( pPager->doNotSpill==1 );
-+    pPager->doNotSpill--;
-+    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((int)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;
-+      }
- 
--    if( rc==SQLITE_OK ){
--      pager_reset(pPager);
--      pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
--      pPager->pageSize = pageSize;
--      sqlite3PageFree(pPager->pTmpSpace);
--      pPager->pTmpSpace = pNew;
--      sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
-+      rc = readMasterJournal(pJournal, zMasterPtr, nMasterPtr);
-+      sqlite3OsClose(pJournal);
-+      if( rc!=SQLITE_OK ){
-+        goto delmaster_out;
-+      }
-+
-+      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 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;
+@@ -45519,7 +48898,39 @@
  }
- 
- /*
--** 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 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 transistions 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 */
-+  /* 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( 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;
-+    /* 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));
-     }
--    p->pExtra = (void *)&p[1];
--    p->flags = PGHDR_MMAP;
--    p->nRef = 1;
--    p->pPager = 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 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));
-+    }
- 
--  p->pgno = pgno;
--  p->pData = pData;
--  pPager->nMmapOut++;
-+    /* 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;
-+    }
- 
--  return SQLITE_OK;
--}
-+    /* 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 );
- 
--/*
--** 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);
-+  }
-+  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) );
-+
-+  if( NEVER(!isOpen(pPager->fd)) ){
-+    assert( pPager->tempFile );
-+    memset(pPg->pData, 0, pPager->pageSize);
-+    return SQLITE_OK;
-+  }
- 
--  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 noising 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;
-+      sqlite3PagerUnref(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 
--   && (pList->pDirty ? pPager->dbSize : pList->pgno+1)>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);
-+  return rc;
-+}
- 
--      /* Encode the database */
--      CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM, pData);
-+/*
-+** 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 */
-+){
-+  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
  
--      /* Write out the page data. */
--      rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);
-+  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
- 
--      /* 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;
-+  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 *p;
-+    PgHdr **ppNext = &pList;
-+    nList = 0;
-+    for(p=pList; (*ppNext = p)!=0; p=p->pDirty){
-+      if( p->pgno<=nTruncate ){
-+        ppNext = &p->pDirty;
-+        nList++;
-       }
--      pPager->aStat[PAGER_STAT_WRITE]++;
--
--      /* Update any backup objects copying the contents of this pager. */
--      sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)pList->pData);
-+    }
-+    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 ){
-+    PgHdr *p;
-+    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(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 doNotSyncSpill flag 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 flag inhibits all cache spilling regardless of whether
--  ** or not a sync is required.  This is set during a rollback.
--  **
--  ** 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
--  ** 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;
--  if( pPager->doNotSpill ) return SQLITE_OK;
--  if( pPager->doNotSyncSpill && (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 */
-+  Bitvec *pDone = 0;       /* Bitvec to ensure pages played back only once */
- 
--  /* 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());
-+  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 output variable to NULL in case an error occurs. */
--  *ppPager = 0;
-+  /* 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;
- 
--#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;
--    }
-+  if( !pSavepoint && pagerUseWal(pPager) ){
-+    return pagerRollbackWal(pPager);
-   }
--#endif
- 
--  /* 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.
-+  /* 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.
-   */
--  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;
-+  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;
-   }
- 
--  /* 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)
-+  /* 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.
-   */
--  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) );
-+  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 );
- 
--  /* 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);
-+    /*
-+    ** 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( nJRec==0 
-+     && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff
-+    ){
-+      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);
-+    }
-+    assert( rc!=SQLITE_DONE );
-   }
--  pPager->pVfs = pVfs;
--  pPager->vfsFlags = vfsFlags;
-+  assert( rc!=SQLITE_OK || pPager->journalOff>=szJ );
- 
--  /* Open the pager file.
-+  /* 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( 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( pSavepoint ){
-+    u32 ii;            /* Loop counter */
-+    i64 offset = (i64)pSavepoint->iSubRec*(4+pPager->pageSize);
- 
--    /* 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( rc==SQLITE_OK && !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 iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
--        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
-+    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);
-     }
--  }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.
--    */ 
--    tempFile = 1;
--    pPager->eState = PAGER_READER;
--    pPager->eLock = EXCLUSIVE_LOCK;
--    readOnly = (vfsFlags&SQLITE_OPEN_READONLY);
-+    assert( rc!=SQLITE_DONE );
-   }
- 
--  /* The following call to PagerSetPagesize() serves to set the value of 
--  ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer.
--  */
-+  sqlite3BitvecDestroy(pDone);
-   if( rc==SQLITE_OK ){
--    assert( pPager->memDb==0 );
--    rc = sqlite3PagerSetPagesize(pPager, &szPageDflt, -1);
--    testcase( rc!=SQLITE_OK );
-+    pPager->journalOff = szJ;
-   }
- 
--  /* If an error occurred in either of the blocks above, free the 
--  ** Pager structure and close the file.
--  */
--  if( rc!=SQLITE_OK ){
--    assert( !pPager->pTmpSpace );
--    sqlite3OsClose(pPager->fd);
--    sqlite3_free(pPager);
--    return rc;
-+  return rc;
-+}
-+
-+/*
-+** 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) ){
-+    sqlite3_int64 sz;
-+    pPager->bUseFetch = (fd->pMethods->iVersion>=3) && pPager->szMmap>0;
-+    sz = pPager->szMmap;
-+    sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz);
-   }
-+#endif
-+}
- 
--  /* Initialize the PCache object. */
--  assert( nExtra<1000 );
--  nExtra = ROUND8(nExtra);
--  sqlite3PcacheOpen(szPageDflt, nExtra, !memDb,
--                    !memDb?pagerStress:0, (void *)pPager, pPager->pPCache);
-+/*
-+** 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);
-+}
- 
--  PAGERTRACE(("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename));
--  IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename))
-+/*
-+** Free as much memory as possible from the pager.
-+*/
-+SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){
-+  sqlite3PcacheShrink(pPager->pPCache);
-+}
- 
--  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; */
--#if 0
--  assert( pPager->state == (tempFile ? PAGER_EXCLUSIVE : PAGER_UNLOCK) );
--#endif
--  /* 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;
-+/*
-+** Adjust the robustness of the database to damage due to OS crashes
-+** or power failures by changing the number of syncs()s when writing
-+** the rollback journal.  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 sqlite3PagerSetSafetyLevel(
-+  Pager *pPager,        /* The pager to set safety level for */
-+  int level,            /* PRAGMA synchronous.  1=OFF, 2=NORMAL, 3=FULL */  
-+  int bFullFsync,       /* PRAGMA fullfsync */
-+  int bCkptFullFsync    /* PRAGMA checkpoint_fullfsync */
-+){
-+  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( bFullFsync ){
-+    pPager->syncFlags = SQLITE_SYNC_FULL;
-+    pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
-+  }else if( bCkptFullFsync ){
-+    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;
-   }
--  /* 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 */
-+}
-+#endif
- 
--  *ppPager = pPager;
--  return SQLITE_OK;
-+/*
-+** 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
-+
-+/*
-+** 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 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
-+
-+  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;
- }
- 
-+/*
-+** Set the busy handler function.
-+**
-+** 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:
-+**
-+**   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 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.
-+*/
-+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;
- 
-+  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);
-+  }
-+}
- 
- /*
--** 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:
-+** Change the page size used by the Pager object. The new page size 
-+** is passed in *pPageSize.
- **
--**   * 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 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).
- **
--** 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.
-+** Otherwise, if all of the following are true:
- **
--** 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. 
-+**   * the new page size (value of *pPageSize) is valid (a power 
-+**     of two between 512 and SQLITE_MAX_PAGE_SIZE, inclusive), and
- **
--** 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.
-+**   * 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.
- */
--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);
-+SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){
-+  int rc = SQLITE_OK;
- 
--  assert( pPager->useJournal );
--  assert( isOpen(pPager->fd) );
--  assert( pPager->eState==PAGER_OPEN );
-+  /* 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( jrnlOpen==0 || ( sqlite3OsDeviceCharacteristics(pPager->jfd) &
--    SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN
--  ));
-+  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;
- 
--  *pExists = 0;
--  if( !jrnlOpen ){
--    rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists);
-+    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( rc==SQLITE_OK ){
-+      pager_reset(pPager);
-+      pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
-+      pPager->pageSize = pageSize;
-+      sqlite3PageFree(pPager->pTmpSpace);
-+      pPager->pTmpSpace = pNew;
-+      sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
-+    }
-   }
--  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 */
-+  *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;
-+}
- 
--      /* Check the size of the database file. If it consists of 0 pages,
--      ** then delete the journal file. See the header comment above for 
--      ** the reasoning here.  Delete the obsolete journal file under
--      ** a RESERVED lock to avoid race conditions and to avoid violating
--      ** [H33020].
--      */
--      rc = pagerPagecount(pPager, &nPage);
--      if( rc==SQLITE_OK ){
--        if( nPage==0 ){
--          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
--            ** its 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 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.
-+**
-+** 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;
- }
- 
- /*
--** 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 following operations are also performed by this function.
-+** 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.
- **
--**   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.
-+** 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;
-+}
-+
-+
-+/*
-+** 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).
- **
--**   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.
-+** 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.
- **
--** 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.
-+** 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.
- */
--SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
--  int rc = SQLITE_OK;                /* Return code */
-+static int pager_wait_on_lock(Pager *pPager, int locktype){
-+  int rc;                              /* Return code */
- 
--  /* 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.
-+  /* Check that this is either a no-op (because the requested lock is 
-+  ** already held, or one of the transistions that the busy-handler
-+  ** may be invoked during, according to the comment above
-+  ** sqlite3PagerSetBusyhandler().
-   */
--  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; }
-+  assert( (pPager->eLock>=locktype)
-+       || (pPager->eLock==NO_LOCK && locktype==SHARED_LOCK)
-+       || (pPager->eLock==RESERVED_LOCK && locktype==EXCLUSIVE_LOCK)
-+  );
- 
--  if( !pagerUseWal(pPager) && pPager->eState==PAGER_OPEN ){
--    int bHotJournal = 1;          /* True if there exists a hot journal-file */
-+  do {
-+    rc = pagerLockDb(pPager, locktype);
-+  }while( rc==SQLITE_BUSY && pPager->xBusyHandler(pPager->pBusyHandlerArg) );
-+  return rc;
-+}
- 
--    assert( !MEMDB );
-+/*
-+** 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
- 
--    rc = pager_wait_on_lock(pPager, SHARED_LOCK);
--    if( rc!=SQLITE_OK ){
--      assert( pPager->eLock==NO_LOCK || pPager->eLock==UNKNOWN_LOCK );
--      goto failed;
--    }
-+/*
-+** 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;
- 
--    /* 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 ){
--      goto failed;
--    }
--    if( bHotJournal ){
--      if( pPager->readOnly ){
--        rc = SQLITE_READONLY_ROLLBACK;
--        goto failed;
--      }
-+  /* 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. */
-+}
- 
--      /* 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);
--      }
- 
--      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;
--      }
-+/*
-+** 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;
-+}
- 
--      assert( pPager->eState==PAGER_OPEN );
--      assert( (pPager->eLock==SHARED_LOCK)
--           || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK)
--      );
-+/*
-+** 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( !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.
--      **
--      ** 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)];
-+  assert( p->pExtra==(void *)&p[1] );
-+  assert( p->pPage==0 );
-+  assert( p->flags==PGHDR_MMAP );
-+  assert( p->pPager==pPager );
-+  assert( p->nRef==1 );
- 
--      rc = pagerPagecount(pPager, &nPage);
--      if( rc ) goto failed;
-+  p->pgno = pgno;
-+  p->pData = pData;
-+  pPager->nMmapOut++;
- 
--      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));
--      }
-+  return SQLITE_OK;
-+}
- 
--      if( memcmp(pPager->dbFileVers, dbFileVers, sizeof(dbFileVers))!=0 ){
--        pager_reset(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;
- 
--        /* 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);
--        }
--      }
--    }
-+  assert( pPager->fd->pMethods->iVersion>=3 );
-+  sqlite3OsUnfetch(pPager->fd, (i64)(pPg->pgno-1)*pPager->pageSize, pPg->pData);
-+}
- 
--    /* 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
-+/*
-+** 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( pagerUseWal(pPager) ){
--    assert( rc==SQLITE_OK );
--    rc = pagerBeginReadTransaction(pPager);
--  }
- 
--  if( pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){
--    rc = pagerPagecount(pPager, &pPager->dbSize);
--  }
-+/*
-+** Shutdown the page cache.  Free all memory and close all files.
-+**
-+** 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.
-+**
-+** 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 sqlite3PagerClose(Pager *pPager){
-+  u8 *pTmp = (u8 *)pPager->pTmpSpace;
- 
-- failed:
--  if( rc!=SQLITE_OK ){
--    assert( !MEMDB );
-+  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;
-+#endif
-+  pager_reset(pPager);
-+  if( MEMDB ){
-     pager_unlock(pPager);
--    assert( pPager->eState==PAGER_OPEN );
-   }else{
--    pPager->eState = PAGER_READER;
-+    /* 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);
-   }
--  return rc;
-+  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);
+-#endif /* SQLITE_OMIT_DISKIO */
++#endif /* SQLITE_OMIT_DISKIO */
 +
++/* BEGIN SQLCIPHER */
 +#ifdef SQLITE_HAS_CODEC
-+  if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
-+#endif
-+
-+  assert( !pPager->aSavepoint && !pPager->pInJournal );
-+  assert( !isOpen(pPager->jfd) && !isOpen(pPager->sjfd) );
-+
-+  sqlite3_free(pPager);
-+  return SQLITE_OK;
- }
- 
-+#if !defined(NDEBUG) || defined(SQLITE_TEST)
- /*
--** 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);
--  }
-+** Return the page number for page pPg.
-+*/
-+SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage *pPg){
-+  return pPg->pgno;
- }
-+#endif
- 
- /*
--** 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. 
-+** Increment the reference count for page pPg.
-+*/
-+SQLITE_PRIVATE void sqlite3PagerRef(DbPage *pPg){
-+  sqlite3PcacheRef(pPg);
++SQLITE_PRIVATE void sqlite3pager_get_codec(Pager *pPager, void **ctx) {
++  *ctx = pPager->pCodec;
 +}
 +
-+/*
-+** 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 noContent is true, it means that we do not care about the contents
--** of the page. This occurs in two seperate scenarios:
-+** 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:
- **
--**   a) When reading a free-list leaf page from the database, and
-+**   * If the journal file is an in-memory journal file, no action need
-+**     be taken.
- **
--**   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.
-+**   * 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 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.
-+**   * If the device does not support the SEQUENTIAL property, then 
-+**     journal file is synced.
- **
--** The acquisition might fail for several reasons.  In all cases,
--** an appropriate error code is returned and *ppPage is set to NULL.
-+** Or, in pseudo-code:
- **
--** 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.
-+**   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.
- */
--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_ACQUIRE_XXX flags */
--){
--  int rc = SQLITE_OK;
--  PgHdr *pPg = 0;
--  u32 iFrame = 0;                 /* Frame to read from WAL file */
--  const int noContent = (flags & PAGER_ACQUIRE_NOCONTENT);
-+static int syncJournal(Pager *pPager, int newHdr){
-+  int rc;                         /* Return code */
- 
--  /* 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_ACQUIRE_READONLY))
--#ifdef SQLITE_HAS_CODEC
--   && pPager->xCodec==0
--#endif
-+  assert( pPager->eState==PAGER_WRITER_CACHEMOD
-+       || pPager->eState==PAGER_WRITER_DBMOD
-   );
--
--  assert( pPager->eState>=PAGER_READER );
-   assert( assert_pager_state(pPager) );
--  assert( noContent==0 || bMmapOk==0 );
--
--  if( pgno==0 ){
--    return SQLITE_CORRUPT_BKPT;
--  }
-+  assert( !pagerUseWal(pPager) );
- 
--  /* 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{
-+  rc = sqlite3PagerExclusiveLock(pPager);
-+  if( rc!=SQLITE_OK ) return rc;
- 
--    if( bMmapOk && pagerUseWal(pPager) ){
--      rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
--      if( rc!=SQLITE_OK ) goto pager_acquire_err;
--    }
-+  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( iFrame==0 && bMmapOk ){
--      void *pData = 0;
-+      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];
- 
--      rc = sqlite3OsFetch(pPager->fd, 
--          (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData
--      );
-+        memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic));
-+        put32bits(&zHeader[sizeof(aJournalMagic)], pPager->nRec);
- 
--      if( rc==SQLITE_OK && pData ){
--        if( pPager->eState>PAGER_READER ){
--          (void)sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &pPg);
-+        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( pPg==0 ){
--          rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg);
--        }else{
--          sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData);
-+        if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
-+          return rc;
-         }
--        if( pPg ){
--          assert( rc==SQLITE_OK );
--          *ppPage = pPg;
--          return SQLITE_OK;
-+
-+        /* 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( rc!=SQLITE_OK ){
--        goto pager_acquire_err;
-+      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;
-+      }
-+
-+      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;
-     }
-+  }
- 
--    rc = sqlite3PcacheFetch(pPager->pPCache, pgno, 1, ppPage);
-+  /* 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;
++SQLITE_PRIVATE int sqlite3pager_is_mj_pgno(Pager *pPager, Pgno pgno) {
++  return (PAGER_MJ_PGNO(pPager) == pgno) ? 1 : 0;
 +}
 +
-+/*
-+** 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.
-+*/
-+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);
-   }
- 
--  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;
-+  /* 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 
-+   && (pList->pDirty ? pPager->dbSize : pList->pgno+1)>pPager->dbHintSize 
-+  ){
-+    sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize;
-+    sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile);
-+    pPager->dbHintSize = pPager->dbSize;
-   }
--  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;
-+  while( rc==SQLITE_OK && pList ){
-+    Pgno pgno = pList->pgno;
- 
--  }else{
--    /* The pager cache has created a new page. Its content needs to 
--    ** be initialized.  */
-+    /* 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 */    
- 
--    pPg = *ppPage;
--    pPg->pPager = pPager;
-+      assert( (pList->flags&PGHDR_NEED_SYNC)==0 );
-+      if( pList->pgno==1 ) pager_write_changecounter(pList);
- 
--    /* 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;
--    }
-+      /* Encode the database */
-+      CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM, pData);
- 
--    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;
-+      /* 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. 
-+      */
-+      if( pgno==1 ){
-+        memcpy(&pPager->dbFileVers, &pData[24], sizeof(pPager->dbFileVers));
-       }
--      assert( pPg->pPager==pPager );
--      pPager->aStat[PAGER_STAT_MISS]++;
--      rc = readDbPage(pPg, iFrame);
--      if( rc!=SQLITE_OK ){
--        goto pager_acquire_err;
-+      if( pgno>pPager->dbFileSize ){
-+        pPager->dbFileSize = pgno;
-       }
--    }
--    pager_set_pagehash(pPg);
--  }
-+      pPager->aStat[PAGER_STAT_WRITE]++;
- 
--  return SQLITE_OK;
-+      /* Update any backup objects copying the contents of this pager. */
-+      sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)pList->pData);
- 
--pager_acquire_err:
--  assert( rc!=SQLITE_OK );
--  if( pPg ){
--    sqlite3PcacheDrop(pPg);
-+      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;
-   }
--  pagerUnlockIfUnused(pPager);
- 
--  *ppPage = 0;
-   return rc;
- }
- 
- /*
--** 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 DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
--  PgHdr *pPg = 0;
--  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;
--}
--
--/*
--** Release a page reference.
-+** Ensure that the sub-journal file is open. If it is already open, this 
-+** function is a no-op.
- **
--** 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_OK is returned if everything goes according to plan. An 
-+** SQLITE_IOERR_XXX error code is returned if a call to sqlite3OsOpen() 
-+** fails.
- */
--SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){
--  if( pPg ){
--    Pager *pPager = pPg->pPager;
--    if( pPg->flags & PGHDR_MMAP ){
--      pagerReleaseMapPage(pPg);
-+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{
--      sqlite3PcacheRelease(pPg);
-+      rc = pagerOpentemp(pPager, pPager->sjfd, SQLITE_OPEN_SUBJOURNAL);
-     }
--    pagerUnlockIfUnused(pPager);
-   }
-+  return rc;
- }
- 
- /*
--** 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.
--**
--** 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 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. 
-+** 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.
- **
--** Whether or not the journal file is opened by this function, the
--** Pager.pInJournal bitvec structure is allocated.
-+** If successful, set the bit corresponding to pPg->pgno in the bitvecs
-+** for all open savepoints before returning.
- **
--** 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.
-+** 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 pager_open_journal(Pager *pPager){
--  int rc = SQLITE_OK;                        /* Return code */
--  sqlite3_vfs * const pVfs = pPager->pVfs;   /* Local cache of vfs pointer */
-+static int subjournalPage(PgHdr *pPg){
-+  int rc = SQLITE_OK;
-+  Pager *pPager = pPg->pPager;
-+  if( pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
- 
--  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;
-+    /* 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(pPg) 
-+         || pPg->pgno>pPager->dbOrigSize 
-+    );
-+    rc = openSubJournal(pPager);
- 
--  if( !pagerUseWal(pPager) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
--    pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize);
--    if( pPager->pInJournal==0 ){
--      return SQLITE_NOMEM;
--    }
-+    /* 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;
-   
--    /* 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)
--          );
--  #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
-+      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);
-       }
--      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;
--  }
--
-+  if( rc==SQLITE_OK ){
-+    pPager->nSubRec++;
-+    assert( pPager->nSavepoint>0 );
-+    rc = addToSavepointBitvecs(pPager, pPg->pgno);
-+  }
-   return rc;
- }
- 
- /*
--** Begin a write-transaction on the specified pager object. If a 
--** write-transaction has already been opened, this function is a no-op.
-+** 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.
- **
--** 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 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 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.
-+** 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.
- */
--SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){
-+static int pagerStress(void *p, PgHdr *pPg){
-+  Pager *pPager = (Pager *)p;
-   int rc = SQLITE_OK;
- 
--  if( pPager->errCode ) return pPager->errCode;
--  assert( pPager->eState>=PAGER_READER && pPager->eState<PAGER_ERROR );
--  pPager->subjInMemory = (u8)subjInMemory;
--
--  if( ALWAYS(pPager->eState==PAGER_READER) ){
--    assert( pPager->pInJournal==0 );
-+  assert( pPg->pPager==pPager );
-+  assert( pPg->flags&PGHDR_DIRTY );
- 
--    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);
--      }
-+  /* The doNotSyncSpill flag 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 flag inhibits all cache spilling regardless of whether
-+  ** or not a sync is required.  This is set during a rollback.
-+  **
-+  ** 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
-+  ** 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;
-+  if( pPager->doNotSpill ) return SQLITE_OK;
-+  if( pPager->doNotSyncSpill && (pPg->flags & PGHDR_NEED_SYNC)!=0 ){
-+    return SQLITE_OK;
-+  }
- 
--      /* 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);
--      }
-+  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 ){
--      /* 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;
-+      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);
-     }
-+  }
- 
--    assert( rc==SQLITE_OK || pPager->eState==PAGER_READER );
--    assert( rc!=SQLITE_OK || pPager->eState==PAGER_WRITER_LOCKED );
--    assert( assert_pager_state(pPager) );
-+  /* Mark the page as clean. */
-+  if( rc==SQLITE_OK ){
-+    PAGERTRACE(("STRESS %d page %d\n", PAGERID(pPager), pPg->pgno));
-+    sqlite3PcacheMakeClean(pPg);
-   }
- 
--  PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager)));
--  return rc;
-+  return pager_error(pPager, 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.
-+** 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 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.
-+**
-+** 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.
- */
--static int pager_write(PgHdr *pPg){
--  void *pData = pPg->pData;
--  Pager *pPager = pPg->pPager;
--  int rc = SQLITE_OK;
-+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 */
- 
--  /* 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.
-+  /* 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).
-   */
--  assert( pPager->eState==PAGER_WRITER_LOCKED
--       || pPager->eState==PAGER_WRITER_CACHEMOD
--       || pPager->eState==PAGER_WRITER_DBMOD
--  );
--  assert( assert_pager_state(pPager) );
--
--  /* If an error has been previously detected, report the same error
--  ** again. This should not happen, but the check provides robustness. */
--  if( NEVER(pPager->errCode) )  return pPager->errCode;
-+  if( sqlite3JournalSize(pVfs)>sqlite3MemJournalSize() ){
-+    journalFileSize = ROUND8(sqlite3JournalSize(pVfs));
-+  }else{
-+    journalFileSize = ROUND8(sqlite3MemJournalSize());
-+  }
- 
--  /* Higher-level routines never call this function if database is not
--  ** writable.  But check anyway, just for robustness. */
--  if( NEVER(pPager->readOnly) ) return SQLITE_PERM;
-+  /* Set the output variable to NULL in case an error occurs. */
-+  *ppPager = 0;
- 
--  CHECK_PAGE(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;
-+    }
-+  }
-+#endif
- 
--  /* 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.
-+  /* 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( pPager->eState==PAGER_WRITER_LOCKED ){
--    rc = pager_open_journal(pPager);
--    if( rc!=SQLITE_OK ) return rc;
-+  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;
-+    }
-   }
--  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.
-+  /* 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)
-   */
--  sqlite3PcacheMakeDirty(pPg);
--  if( pageInJournal(pPg) && !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( !pageInJournal(pPg) && !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, 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;
-+  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) );
- 
--        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;
-+  /* 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;
- 
--        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 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);
- 
--        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;
-+    /* 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( rc==SQLITE_OK && !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;
-         }
--      }else{
--        if( pPager->eState!=PAGER_WRITER_DBMOD ){
--          pPg->flags |= PGHDR_NEED_SYNC;
-+      }
-+#ifdef SQLITE_ENABLE_ATOMIC_WRITE
-+      {
-+        int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
-+        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;
-+          }
-         }
--        PAGERTRACE(("APPEND %d page %d needSync=%d\n",
--                PAGERID(pPager), pPg->pgno,
--               ((pPg->flags&PGHDR_NEED_SYNC)?1:0)));
-       }
-+#endif
-     }
--  
--    /* 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( subjRequiresPage(pPg) ){
--      rc = subjournalPage(pPg);
--    }
-+  }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.
-+    */ 
-+    tempFile = 1;
-+    pPager->eState = PAGER_READER;
-+    pPager->eLock = EXCLUSIVE_LOCK;
-+    readOnly = (vfsFlags&SQLITE_OPEN_READONLY);
-+  }
-+
-+  /* 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 );
-+  }
-+
-+  /* If an error occurred in either of the blocks above, free the 
-+  ** Pager structure and close the file.
-+  */
-+  if( rc!=SQLITE_OK ){
-+    assert( !pPager->pTmpSpace );
-+    sqlite3OsClose(pPager->fd);
-+    sqlite3_free(pPager);
-+    return rc;
-   }
- 
--  /* Update the database size and return.
--  */
--  if( pPager->dbSize<pPg->pgno ){
--    pPager->dbSize = pPg->pgno;
-+  /* 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))
-+
-+  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; */
-+#if 0
-+  assert( pPager->state == (tempFile ? PAGER_EXCLUSIVE : PAGER_UNLOCK) );
-+#endif
-+  /* 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;
-   }
--  return rc;
-+  /* 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;
- }
- 
-+
-+
- /*
--** 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.
-+** 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 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 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 an error occurs, SQLITE_NOMEM or an IO error code is returned
--** as appropriate. Otherwise, SQLITE_OK.
-+** 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 sqlite3PagerWrite(DbPage *pDbPage){
--  int rc = SQLITE_OK;
--
--  PgHdr *pPg = pDbPage;
--  Pager *pPager = pPg->pPager;
--  Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);
-+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( (pPg->flags & PGHDR_MMAP)==0 );
--  assert( pPager->eState>=PAGER_WRITER_LOCKED );
--  assert( pPager->eState!=PAGER_ERROR );
--  assert( assert_pager_state(pPager) );
-+  assert( pPager->useJournal );
-+  assert( isOpen(pPager->fd) );
-+  assert( pPager->eState==PAGER_OPEN );
- 
--  if( nPagePerSector>1 ){
--    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 */
-+  assert( jrnlOpen==0 || ( sqlite3OsDeviceCharacteristics(pPager->jfd) &
-+    SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN
-+  ));
- 
--    /* Set the doNotSyncSpill flag 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->doNotSyncSpill==0 );
--    pPager->doNotSyncSpill++;
-+  *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 */
- 
--    /* 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.
-+    /* 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.
-     */
--    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);
-+    rc = sqlite3OsCheckReservedLock(pPager->fd, &locked);
-+    if( rc==SQLITE_OK && !locked ){
-+      Pgno nPage;                 /* Number of pages in database file */
- 
--    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);
-+      /* Check the size of the database file. If it consists of 0 pages,
-+      ** then delete the journal file. See the header comment above for 
-+      ** the reasoning here.  Delete the obsolete journal file under
-+      ** a RESERVED lock to avoid race conditions and to avoid violating
-+      ** [H33020].
-+      */
-+      rc = pagerPagecount(pPager, &nPage);
-+      if( rc==SQLITE_OK ){
-+        if( nPage==0 ){
-+          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 ){
--            rc = pager_write(pPage);
--            if( pPage->flags&PGHDR_NEED_SYNC ){
--              needSync = 1;
-+            u8 first = 0;
-+            rc = sqlite3OsRead(pPager->jfd, (void *)&first, 1, 0);
-+            if( rc==SQLITE_IOERR_SHORT_READ ){
-+              rc = SQLITE_OK;
-             }
--            sqlite3PagerUnref(pPage);
-+            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
-+            ** its 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;
-           }
-         }
--      }else if( (pPage = pager_lookup(pPager, pg))!=0 ){
--        if( pPage->flags&PGHDR_NEED_SYNC ){
--          needSync = 1;
--        }
--        sqlite3PagerUnref(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;
--          sqlite3PagerUnref(pPage);
--        }
-       }
-     }
--
--    assert( pPager->doNotSyncSpill==1 );
--    pPager->doNotSyncSpill--;
--  }else{
--    rc = pager_write(pDbPage);
-   }
--  return rc;
--}
- 
--/*
--** 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;
-+  return rc;
- }
--#endif
- 
- /*
--** 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.
-+** 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.
- **
--** 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);
--  }
--}
--
--/*
--** 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.
-+** The following operations are also performed by this function.
- **
--** 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.
-+**   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.
- **
--** 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.
-+**   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 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.
-+** 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.
- */
--static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
--  int rc = SQLITE_OK;
--
--  assert( pPager->eState==PAGER_WRITER_CACHEMOD
--       || pPager->eState==PAGER_WRITER_DBMOD
--  );
--  assert( assert_pager_state(pPager) );
-+SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
-+  int rc = SQLITE_OK;                /* Return code */
- 
--  /* 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.
-+  /* 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.
-   */
--#ifndef SQLITE_ENABLE_ATOMIC_WRITE
--# define DIRECT_MODE 0
--  assert( isDirectMode==0 );
--  UNUSED_PARAMETER(isDirectMode);
--#else
--# define DIRECT_MODE isDirectMode
--#endif
-+  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( !pPager->changeCountDone && ALWAYS(pPager->dbSize>0) ){
--    PgHdr *pPgHdr;                /* Reference to page 1 */
-+  if( !pagerUseWal(pPager) && pPager->eState==PAGER_OPEN ){
-+    int bHotJournal = 1;          /* True if there exists a hot journal-file */
- 
--    assert( !pPager->tempFile && isOpen(pPager->fd) );
-+    assert( !MEMDB );
- 
--    /* Open page 1 of the file for writing. */
--    rc = sqlite3PagerGet(pPager, 1, &pPgHdr);
--    assert( pPgHdr==0 || rc==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 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 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( !DIRECT_MODE && ALWAYS(rc==SQLITE_OK) ){
--      rc = sqlite3PagerWrite(pPgHdr);
-+    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;
-+      }
-+
-+      /* 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);
-+      }
-+
-+      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;
-+      }
-+
-+      assert( pPager->eState==PAGER_OPEN );
-+      assert( (pPager->eLock==SHARED_LOCK)
-+           || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK)
-+      );
-     }
- 
--    if( rc==SQLITE_OK ){
--      /* Actually do the update of the change counter */
--      pager_write_changecounter(pPgHdr);
-+    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.
-+      **
-+      ** 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;
- 
--      /* 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]++;
--        }
--        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;
-+      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{
--        pPager->changeCountDone = 1;
-+        memset(dbFileVers, 0, sizeof(dbFileVers));
-+      }
-+
-+      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);
-+        }
-       }
-     }
- 
--    /* Release the page reference. */
--    sqlite3PagerUnref(pPgHdr);
-+    /* 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
-   }
--  return rc;
--}
- 
--/*
--** 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 sqlite3PagerSync(Pager *pPager){
--  int rc = SQLITE_OK;
--  if( !pPager->noSync ){
--    assert( !MEMDB );
--    rc = sqlite3OsSync(pPager->fd, pPager->syncFlags);
--  }else if( isOpen(pPager->fd) ){
-+  if( pagerUseWal(pPager) ){
-+    assert( rc==SQLITE_OK );
-+    rc = pagerBeginReadTransaction(pPager);
-+  }
-+
-+  if( pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){
-+    rc = pagerPagecount(pPager, &pPager->dbSize);
-+  }
-+
-+ failed:
-+  if( rc!=SQLITE_OK ){
-     assert( !MEMDB );
--    rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC_OMITTED, 0);
--    if( rc==SQLITE_NOTFOUND ){
--      rc = SQLITE_OK;
--    }
-+    pager_unlock(pPager);
-+    assert( pPager->eState==PAGER_OPEN );
-+  }else{
-+    pPager->eState = PAGER_READER;
-   }
-   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.
-+** If the reference count has reached zero, rollback any active
-+** transaction and unlock the pager.
- **
--** 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 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);
-+** 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);
-   }
--  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).
-+** 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.
- **
--** This routine ensures that:
-+** 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 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 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.
- **
--** 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).
-+** 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. 
- **
--** Note that if zMaster==NULL, this does not overwrite a previous value
--** passed to an sqlite3PagerCommitPhaseOne() call.
-+** If noContent is true, it means that we do not care about the contents
-+** of the page. This occurs in two seperate scenarios:
- **
--** 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.
-+**   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.
-+**
-+** 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 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 */
-+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_ACQUIRE_XXX flags */
- ){
--  int rc = SQLITE_OK;             /* Return code */
-+  int rc = SQLITE_OK;
-+  PgHdr *pPg = 0;
-+  u32 iFrame = 0;                 /* Frame to read from WAL file */
-+  const int noContent = (flags & PAGER_ACQUIRE_NOCONTENT);
- 
--  assert( pPager->eState==PAGER_WRITER_LOCKED
--       || pPager->eState==PAGER_WRITER_CACHEMOD
--       || pPager->eState==PAGER_WRITER_DBMOD
--       || pPager->eState==PAGER_ERROR
-+  /* 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_ACQUIRE_READONLY))
-+#ifdef SQLITE_HAS_CODEC
-+   && pPager->xCodec==0
-+#endif
-   );
-+
-+  assert( pPager->eState>=PAGER_READER );
-   assert( assert_pager_state(pPager) );
-+  assert( noContent==0 || bMmapOk==0 );
- 
--  /* If a prior error occurred, report that error again. */
--  if( NEVER(pPager->errCode) ) return pPager->errCode;
-+  if( pgno==0 ){
-+    return SQLITE_CORRUPT_BKPT;
-+  }
- 
--  PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n", 
--      pPager->zFilename, zMaster, pPager->dbSize));
-+  /* 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 no database changes have been made, return early. */
--  if( pPager->eState<PAGER_WRITER_CACHEMOD ) return SQLITE_OK;
-+    if( bMmapOk && pagerUseWal(pPager) ){
-+      rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
-+      if( rc!=SQLITE_OK ) goto pager_acquire_err;
-+    }
- 
--  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( iFrame==0 && bMmapOk ){
-+      void *pData = 0;
-+
-+      rc = sqlite3OsFetch(pPager->fd, 
-+          (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData
-       );
--      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( rc==SQLITE_OK && pData ){
-+        if( pPager->eState>PAGER_READER ){
-+          (void)sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &pPg);
-+        }
-+        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;
-         }
-       }
--  #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;
-+        goto pager_acquire_err;
-       }
--      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;
-+    rc = sqlite3PcacheFetch(pPager->pPCache, pgno, 1, ppPage);
-+  }
-+
-+  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;
-+    }
-+
-+    if( MEMDB || pPager->dbSize<pgno || noContent || !isOpen(pPager->fd) ){
-+      if( pgno>pPager->mxPgno ){
-+        rc = SQLITE_FULL;
-+        goto pager_acquire_err;
-       }
--  
--      /* Finally, sync the database file. */
--      if( !noSync ){
--        rc = sqlite3PagerSync(pPager);
-+      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;
-       }
--      IOTRACE(("DBSYNC %p\n", pPager))
-     }
-+    pager_set_pagehash(pPg);
-   }
- 
--commit_phase_one_exit:
--  if( rc==SQLITE_OK && !pagerUseWal(pPager) ){
--    pPager->eState = PAGER_WRITER_FINISHED;
-+  return SQLITE_OK;
-+
-+pager_acquire_err:
-+  assert( rc!=SQLITE_OK );
-+  if( pPg ){
-+    sqlite3PcacheDrop(pPg);
-   }
-+  pagerUnlockIfUnused(pPager);
-+
-+  *ppPage = 0;
-   return rc;
- }
- 
--
- /*
--** 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.
-+** 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. 
- **
--** If an error occurs, an IO error code is returned and the pager
--** moves into the error state. Otherwise, SQLITE_OK is returned.
-+** 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 sqlite3PagerCommitPhaseTwo(Pager *pPager){
--  int rc = SQLITE_OK;                  /* Return code */
--
--  /* 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;
--
--  assert( pPager->eState==PAGER_WRITER_LOCKED
--       || pPager->eState==PAGER_WRITER_FINISHED
--       || (pagerUseWal(pPager) && pPager->eState==PAGER_WRITER_CACHEMOD)
--  );
--  assert( assert_pager_state(pPager) );
-+SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
-+  PgHdr *pPg = 0;
-+  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;
++SQLITE_PRIVATE sqlite3_file *sqlite3Pager_get_fd(Pager *pPager) {
++  return (isOpen(pPager->fd)) ? pPager->fd : NULL;
 +}
- 
--  /* 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 );
--    pPager->eState = PAGER_READER;
--    return SQLITE_OK;
-+/*
-+** 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.
-+*/
-+SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){
-+  if( pPg ){
-+    Pager *pPager = pPg->pPager;
-+    if( pPg->flags & PGHDR_MMAP ){
-+      pagerReleaseMapPage(pPg);
-+    }else{
-+      sqlite3PcacheRelease(pPg);
-+    }
-+    pagerUnlockIfUnused(pPager);
-   }
--
--  PAGERTRACE(("COMMIT %d\n", PAGERID(pPager)));
--  rc = pager_end_transaction(pPager, pPager->setMaster, 1);
--  return pager_error(pPager, rc);
- }
- 
- /*
--** 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 is already in PAGER_ERROR state when this function is called,
--** it returns Pager.errCode immediately. No work is performed in this case.
--**
--** Otherwise, in rollback mode, this function performs two functions:
-+** 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.
- **
--**   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
-+** 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.
- **
--**   2) It finalizes the journal file, so that it is not used for hot
--**      rollback at any point in the future.
-+** 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. 
- **
--** Finalization of the journal file (task 2) is only performed if the 
--** rollback is successful.
-+** Whether or not the journal file is opened by this function, the
-+** Pager.pInJournal bitvec structure is allocated.
- **
--** 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.
-+** 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.
- */
--SQLITE_PRIVATE int sqlite3PagerRollback(Pager *pPager){
--  int rc = SQLITE_OK;                  /* Return code */
--  PAGERTRACE(("ROLLBACK %d\n", PAGERID(pPager)));
-+static int pager_open_journal(Pager *pPager){
-+  int rc = SQLITE_OK;                        /* Return code */
-+  sqlite3_vfs * const pVfs = pPager->pVfs;   /* Local cache of vfs pointer */
- 
--  /* 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( pPager->eState==PAGER_WRITER_LOCKED );
-   assert( assert_pager_state(pPager) );
--  if( pPager->eState==PAGER_ERROR ) return pPager->errCode;
--  if( pPager->eState<=PAGER_READER ) return SQLITE_OK;
-+  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;
- 
--  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;
-+  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)
-+          );
-+  #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
-+      }
-+      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);
-     }
--  }else{
--    rc = pager_playback(pPager, 0);
-   }
- 
--  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 );
-+  if( rc!=SQLITE_OK ){
-+    sqlite3BitvecDestroy(pPager->pInJournal);
-+    pPager->pInJournal = 0;
-+  }else{
-+    assert( pPager->eState==PAGER_WRITER_LOCKED );
-+    pPager->eState = PAGER_WRITER_CACHEMOD;
-+  }
- 
--  /* 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);
-+  return rc;
- }
- 
- /*
--** Return TRUE if the database file is opened read-only.  Return FALSE
--** if the database is (in theory) writable.
-+** Begin a write-transaction on the specified pager object. If a 
-+** write-transaction has already been opened, 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.
-+**
-+** 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 u8 sqlite3PagerIsreadonly(Pager *pPager){
--  return pPager->readOnly;
--}
-+SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){
-+  int rc = SQLITE_OK;
- 
--/*
--** Return the number of references to the pager.
--*/
--SQLITE_PRIVATE int sqlite3PagerRefcount(Pager *pPager){
--  return sqlite3PcacheRefCount(pPager->pPCache);
--}
-+  if( pPager->errCode ) return pPager->errCode;
-+  assert( pPager->eState>=PAGER_READER && pPager->eState<PAGER_ERROR );
-+  pPager->subjInMemory = (u8)subjInMemory;
- 
--/*
--** 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;
--}
-+  if( ALWAYS(pPager->eState==PAGER_READER) ){
-+    assert( pPager->pInJournal==0 );
- 
--/*
--** Return the number of references to the specified page.
--*/
--SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage *pPage){
--  return sqlite3PcachePageRefcount(pPage);
--}
-+    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);
-+      }
- 
--#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;
-+      /* 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);
-+      }
-+    }
-+
-+    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;
-+    }
-+
-+    assert( rc==SQLITE_OK || pPager->eState==PAGER_READER );
-+    assert( rc!=SQLITE_OK || pPager->eState==PAGER_WRITER_LOCKED );
-+    assert( assert_pager_state(pPager) );
-+  }
 +
-+  PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager)));
-+  return rc;
- }
--#endif
- 
- /*
--** 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.
-+** 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 void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){
-+static int pager_write(PgHdr *pPg){
-+  void *pData = pPg->pData;
-+  Pager *pPager = pPg->pPager;
-+  int rc = SQLITE_OK;
- 
--  assert( eStat==SQLITE_DBSTATUS_CACHE_HIT
--       || eStat==SQLITE_DBSTATUS_CACHE_MISS
--       || eStat==SQLITE_DBSTATUS_CACHE_WRITE
-+  /* 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( 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 );
-+  /* If an error has been previously detected, report the same error
-+  ** again. This should not happen, but the check provides robustness. */
-+  if( NEVER(pPager->errCode) )  return pPager->errCode;
- 
--  *pnVal += pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT];
--  if( reset ){
--    pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT] = 0;
-+  /* Higher-level routines never call this function if database is not
-+  ** writable.  But check anyway, just for robustness. */
-+  if( NEVER(pPager->readOnly) ) return SQLITE_PERM;
-+
-+  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;
-   }
--}
-+  assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
-+  assert( assert_pager_state(pPager) );
- 
--/*
--** Return true if this is an in-memory pager.
--*/
--SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){
--  return MEMDB;
--}
-+  /* Mark the page as dirty.  If the page has already been written
-+  ** to the journal then we can return right away.
-+  */
-+  sqlite3PcacheMakeDirty(pPg);
-+  if( pageInJournal(pPg) && !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( !pageInJournal(pPg) && !pagerUseWal(pPager) ){
-+      assert( pagerUseWal(pPager)==0 );
-+      if( pPg->pgno<=pPager->dbOrigSize && isOpen(pPager->jfd) ){
-+        u32 cksum;
-+        char *pData2;
-+        i64 iOff = pPager->journalOff;
- 
--/*
--** 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.
--**
--** 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 */
-+        /* 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->eState>=PAGER_WRITER_LOCKED );
--  assert( assert_pager_state(pPager) );
-+        assert( pPager->journalHdr<=pPager->journalOff );
-+        CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
-+        cksum = pager_cksum(pPager, (u8*)pData2);
- 
--  if( nSavepoint>nCurrent && pPager->useJournal ){
--    int ii;                                 /* Iterator variable */
--    PagerSavepoint *aNew;                   /* New Pager.aSavepoint array */
-+        /* 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;
- 
--    /* 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;
-+        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;
- 
--    /* 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;
-+        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{
--        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);
-+        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)));
-       }
--      pPager->nSavepoint = ii+1;
-     }
--    assert( pPager->nSavepoint==nSavepoint );
--    assertTruncateConstraint(pPager);
-+  
-+    /* 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( subjRequiresPage(pPg) ){
-+      rc = subjournalPage(pPg);
-+    }
-   }
- 
-+  /* Update the database size and return.
-+  */
-+  if( pPager->dbSize<pPg->pgno ){
-+    pPager->dbSize = pPg->pgno;
-+  }
-   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.
--**
--** 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.
--**
--** 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.
--**
--** 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. 
-+** 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.
- **
--** 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.
-+** 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 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 */
-+** If an error occurs, SQLITE_NOMEM or an IO error code is returned
-+** as appropriate. Otherwise, SQLITE_OK.
-+*/
-+SQLITE_PRIVATE int sqlite3PagerWrite(DbPage *pDbPage){
-+  int rc = SQLITE_OK;
- 
--  assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK );
--  assert( iSavepoint>=0 || op==SAVEPOINT_ROLLBACK );
-+  PgHdr *pPg = pDbPage;
-+  Pager *pPager = pPg->pPager;
-+  Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);
- 
--  if( rc==SQLITE_OK && iSavepoint<pPager->nSavepoint ){
--    int ii;            /* Iterator variable */
--    int nNew;          /* Number of remaining savepoints after this op. */
-+  assert( (pPg->flags & PGHDR_MMAP)==0 );
-+  assert( pPager->eState>=PAGER_WRITER_LOCKED );
-+  assert( pPager->eState!=PAGER_ERROR );
-+  assert( assert_pager_state(pPager) );
-+
-+  if( nPagePerSector>1 ){
-+    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 */
-+
-+    /* Set the doNotSyncSpill flag 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->doNotSyncSpill==0 );
-+    pPager->doNotSyncSpill++;
- 
--    /* 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.
-+    /* 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.
-     */
--    nNew = iSavepoint + (( op==SAVEPOINT_RELEASE ) ? 0 : 1);
--    for(ii=nNew; ii<pPager->nSavepoint; ii++){
--      sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint);
-+    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;
-     }
--    pPager->nSavepoint = nNew;
-+    assert(nPage>0);
-+    assert(pg1<=pPg->pgno);
-+    assert((pg1+nPage)>pPg->pgno);
- 
--    /* 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 );
-+    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;
-+            }
-+            sqlite3PagerUnref(pPage);
-+          }
-         }
--        pPager->nSubRec = 0;
-+      }else if( (pPage = pager_lookup(pPager, pg))!=0 ){
-+        if( pPage->flags&PGHDR_NEED_SYNC ){
-+          needSync = 1;
-+        }
-+        sqlite3PagerUnref(pPage);
-       }
-     }
--    /* 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.
-+
-+    /* 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.
-     */
--    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 && needSync ){
-+      assert( !MEMDB );
-+      for(ii=0; ii<nPage; ii++){
-+        PgHdr *pPage = pager_lookup(pPager, pg1+ii);
-+        if( pPage ){
-+          pPage->flags |= PGHDR_NEED_SYNC;
-+          sqlite3PagerUnref(pPage);
-+        }
-+      }
-     }
--  }
- 
-+    assert( pPager->doNotSyncSpill==1 );
-+    pPager->doNotSyncSpill--;
-+  }else{
-+    rc = pager_write(pDbPage);
-+  }
-   return rc;
- }
- 
- /*
--** 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.
-+** 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 const char *sqlite3PagerFilename(Pager *pPager, int nullIfMemDb){
--  return (nullIfMemDb && pPager->memDb) ? "" : pPager->zFilename;
-+#ifndef NDEBUG
-+SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage *pPg){
-+  return pPg->flags&PGHDR_DIRTY;
- }
-+#endif
- 
- /*
--** Return the VFS structure for the pager.
-+** 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 const sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){
--  return pPager->pVfs;
-+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 the file handle for the database file associated
--** with the pager.  This might return NULL if the file has
--** not yet been opened.
-+** 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.
- */
--SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){
--  return pPager->fd;
--}
-+static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
-+  int rc = SQLITE_OK;
- 
--/*
--** Return the full pathname of the journal file.
--*/
--SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager *pPager){
--  return pPager->zJournal;
-+  assert( pPager->eState==PAGER_WRITER_CACHEMOD
-+       || pPager->eState==PAGER_WRITER_DBMOD
-+  );
-+  assert( assert_pager_state(pPager) );
-+
-+  /* 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.
-+  */
-+#ifndef SQLITE_ENABLE_ATOMIC_WRITE
-+# define DIRECT_MODE 0
-+  assert( isDirectMode==0 );
-+  UNUSED_PARAMETER(isDirectMode);
-+#else
-+# define DIRECT_MODE isDirectMode
-+#endif
-+
-+  if( !pPager->changeCountDone && ALWAYS(pPager->dbSize>0) ){
-+    PgHdr *pPgHdr;                /* Reference to page 1 */
-+
-+    assert( !pPager->tempFile && isOpen(pPager->fd) );
-+
-+    /* Open page 1 of the file for writing. */
-+    rc = sqlite3PagerGet(pPager, 1, &pPgHdr);
-+    assert( pPgHdr==0 || rc==SQLITE_OK );
-+
-+    /* 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( !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]++;
-+        }
-+        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;
-+        }
-+      }else{
-+        pPager->changeCountDone = 1;
-+      }
-+    }
-+
-+    /* Release the page reference. */
-+    sqlite3PagerUnref(pPgHdr);
-+  }
-+  return rc;
- }
- 
- /*
--** Return true if fsync() calls are disabled for this pager.  Return FALSE
--** if fsync()s are executed normally.
-+** 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 sqlite3PagerNosync(Pager *pPager){
--  return pPager->noSync;
-+SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager){
-+  int rc = SQLITE_OK;
-+  if( !pPager->noSync ){
-+    assert( !MEMDB );
-+    rc = sqlite3OsSync(pPager->fd, pPager->syncFlags);
-+  }else if( isOpen(pPager->fd) ){
-+    assert( !MEMDB );
-+    rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC_OMITTED, 0);
-+    if( rc==SQLITE_NOTFOUND ){
-+      rc = SQLITE_OK;
-+    }
-+  }
-+  return rc;
- }
- 
--#ifdef SQLITE_HAS_CODEC
- /*
--** Set or retrieve the codec for this pager
-+** 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.
-+**
-+** 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 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;
-+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 rc;
- }
--#endif
- 
--#ifndef SQLITE_OMIT_AUTOVACUUM
- /*
--** Move the page pPg to location pgno in the file.
-+** 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).
- **
--** 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.
-+** This routine ensures that:
- **
--** 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 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. 
- **
--** 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).
-+** 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).
- **
--** 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.
-+** Note that if zMaster==NULL, this does not overwrite a previous value
-+** passed to an sqlite3PagerCommitPhaseOne() call.
- **
--** This function may return SQLITE_NOMEM or an IO error code if an error
--** occurs. Otherwise, it returns SQLITE_OK.
-+** 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 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 */
-+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 */
- 
--  assert( pPg->nRef>0 );
--  assert( pPager->eState==PAGER_WRITER_CACHEMOD
-+  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) );
- 
--  /* 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;
--  }
--
--  /* 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;
--  }
--
--  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.
--  */
--  if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){
--    needSyncPgno = pPg->pgno;
--    assert( pPager->journalMode==PAGER_JOURNALMODE_OFF ||
--            pageInJournal(pPg) || pPg->pgno>pPager->dbOrigSize );
--    assert( pPg->flags&PGHDR_DIRTY );
--  }
-+  /* If a prior error occurred, report that error again. */
-+  if( NEVER(pPager->errCode) ) return pPager->errCode;
- 
--  /* 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 = pager_lookup(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);
--    }
--  }
-+  PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n", 
-+      pPager->zFilename, zMaster, pPager->dbSize));
- 
--  origPgno = pPg->pgno;
--  sqlite3PcacheMove(pPg, pgno);
--  sqlite3PcacheMakeDirty(pPg);
-+  /* If no database changes have been made, return early. */
-+  if( pPager->eState<PAGER_WRITER_CACHEMOD ) return SQLITE_OK;
- 
--  /* 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);
--    sqlite3PagerUnref(pPgOld);
--  }
-+    /* 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);
- 
--  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);
-+      /* 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;
-       }
--      return rc;
-+  
-+      /* Finally, sync the database file. */
-+      if( !noSync ){
-+        rc = sqlite3PagerSync(pPager);
-+      }
-+      IOTRACE(("DBSYNC %p\n", pPager))
-     }
--    pPgHdr->flags |= PGHDR_NEED_SYNC;
--    sqlite3PcacheMakeDirty(pPgHdr);
--    sqlite3PagerUnref(pPgHdr);
-   }
- 
--  return SQLITE_OK;
--}
--#endif
--
--/*
--** Return a pointer to the data for the specified page.
--*/
--SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *pPg){
--  assert( pPg->nRef>0 || pPg->pPager->memDb );
--  return pPg->pData;
-+commit_phase_one_exit:
-+  if( rc==SQLITE_OK && !pagerUseWal(pPager) ){
-+    pPager->eState = PAGER_WRITER_FINISHED;
-+  }
-+  return rc;
- }
- 
--/*
--** Return a pointer to the Pager.nExtra bytes of "extra" space 
--** allocated along with the specified page.
--*/
--SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *pPg){
--  return pPg->pExtra;
--}
- 
- /*
--** 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.
-+** 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.
- **
--** The returned value is either PAGER_LOCKINGMODE_NORMAL or
--** PAGER_LOCKINGMODE_EXCLUSIVE, indicating the current (possibly updated)
--** locking-mode.
-+** 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 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 int sqlite3PagerCommitPhaseTwo(Pager *pPager){
-+  int rc = SQLITE_OK;                  /* Return code */
-+
-+  /* 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;
-+
-+  assert( pPager->eState==PAGER_WRITER_LOCKED
-+       || pPager->eState==PAGER_WRITER_FINISHED
-+       || (pagerUseWal(pPager) && pPager->eState==PAGER_WRITER_CACHEMOD)
-+  );
-+  assert( assert_pager_state(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 );
-+    pPager->eState = PAGER_READER;
-+    return SQLITE_OK;
-   }
--  return (int)pPager->exclusiveMode;
-+
-+  PAGERTRACE(("COMMIT %d\n", PAGERID(pPager)));
-+  rc = pager_end_transaction(pPager, pPager->setMaster, 1);
-+  return pager_error(pPager, rc);
- }
- 
- /*
--** Set the journal-mode for this pager. Parameter eMode must be one of:
-+** 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.
- **
--**    PAGER_JOURNALMODE_DELETE
--**    PAGER_JOURNALMODE_TRUNCATE
--**    PAGER_JOURNALMODE_PERSIST
--**    PAGER_JOURNALMODE_OFF
--**    PAGER_JOURNALMODE_MEMORY
--**    PAGER_JOURNALMODE_WAL
-+** 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.
- **
--** The journalmode is set to the value specified if the change is allowed.
--** The change may be disallowed for the following reasons:
-+** Otherwise, in rollback mode, this function performs two functions:
- **
--**   *  An in-memory database can only have its journal_mode set to _OFF
--**      or _MEMORY.
-+**   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
- **
--**   *  Temporary databases cannot have _WAL journalmode.
-+**   2) It finalizes the journal file, so that it is not used for hot
-+**      rollback at any point in the future.
- **
--** The returned indicate the current (possibly updated) journal-mode.
-+** 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 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
--
--
--  /* 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 );
--
--  /* 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 );
-+SQLITE_PRIVATE int sqlite3PagerRollback(Pager *pPager){
-+  int rc = SQLITE_OK;                  /* Return code */
-+  PAGERTRACE(("ROLLBACK %d\n", PAGERID(pPager)));
- 
--  /* Do allow the journalmode of an in-memory database to be set to
--  ** anything other than MEMORY or OFF
-+  /* 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.
-   */
--  if( MEMDB ){
--    assert( eOld==PAGER_JOURNALMODE_MEMORY || eOld==PAGER_JOURNALMODE_OFF );
--    if( eMode!=PAGER_JOURNALMODE_MEMORY && eMode!=PAGER_JOURNALMODE_OFF ){
--      eMode = eOld;
--    }
--  }
--
--  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 ){
-+  assert( assert_pager_state(pPager) );
-+  if( pPager->eState==PAGER_ERROR ) return pPager->errCode;
-+  if( pPager->eState<=PAGER_READER ) return SQLITE_OK;
- 
--      /* 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.
-+  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.
-       */
--      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 );
--      }
-+      pPager->errCode = SQLITE_ABORT;
-+      pPager->eState = PAGER_ERROR;
-+      return rc;
-     }
-+  }else{
-+    rc = pager_playback(pPager, 0);
-   }
- 
--  /* Return the new journal mode */
--  return (int)pPager->journalMode;
-+  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 );
-+
-+  /* 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);
- }
- 
- /*
--** Return the current journal mode.
-+** Return TRUE if the database file is opened read-only.  Return FALSE
-+** if the database is (in theory) writable.
- */
--SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager *pPager){
--  return (int)pPager->journalMode;
-+SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager *pPager){
-+  return pPager->readOnly;
- }
- 
- /*
--** 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.
-+** Return the number of references to the pager.
- */
--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;
-+SQLITE_PRIVATE int sqlite3PagerRefcount(Pager *pPager){
-+  return sqlite3PcacheRefCount(pPager->pPCache);
- }
- 
- /*
--** Get/set the size-limit used for persistent journal files.
--**
--** Setting the size limit to -1 means no limit is enforced.
--** An attempt to set a limit smaller than -1 is a no-op.
-+** Return the approximate number of bytes of memory currently
-+** used by the pager and its associated cache.
- */
--SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){
--  if( iLimit>=-1 ){
--    pPager->journalSizeLimit = iLimit;
--    sqlite3WalLimit(pPager->pWal, iLimit);
--  }
--  return pPager->journalSizeLimit;
-+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;
- }
- 
- /*
--** 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.
-+** Return the number of references to the specified page.
- */
--SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){
--  return &pPager->pBackup;
-+SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage *pPage){
-+  return sqlite3PcachePageRefcount(pPage);
- }
- 
--#ifndef SQLITE_OMIT_VACUUM
-+#ifdef SQLITE_TEST
- /*
--** Unless this is an in-memory or temporary database, clear the pager cache.
-+** This routine is used for testing and analysis only.
- */
--SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *pPager){
--  if( !MEMDB && pPager->tempFile==0 ) pager_reset(pPager);
-+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
- 
--#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.
-+** 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 int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){
--  int rc = SQLITE_OK;
--  if( pPager->pWal ){
--    rc = sqlite3WalCheckpoint(pPager->pWal, eMode,
--        pPager->xBusyHandler, pPager->pBusyHandlerArg,
--        pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
--        pnLog, pnCkpt
--    );
--  }
--  return rc;
--}
-+SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){
- 
--SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager){
--  return sqlite3WalCallback(pPager->pWal);
--}
-+  assert( eStat==SQLITE_DBSTATUS_CACHE_HIT
-+       || eStat==SQLITE_DBSTATUS_CACHE_MISS
-+       || eStat==SQLITE_DBSTATUS_CACHE_WRITE
-+  );
- 
--/*
--** 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);
-+  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;
-+  }
- }
- 
- /*
--** Attempt to take an exclusive lock on the database file. If a PENDING lock
--** is obtained instead, immediately release it.
-+** Return true if this is an in-memory pager.
- */
--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;
-+SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){
-+  return MEMDB;
- }
- 
- /*
--** 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.
-+** 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.
-+**
-+** 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.
- */
--static int pagerOpenWal(Pager *pPager){
--  int rc = 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->pWal==0 && pPager->tempFile==0 );
--  assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK );
-+  assert( pPager->eState>=PAGER_WRITER_LOCKED );
-+  assert( assert_pager_state(pPager) );
- 
--  /* 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);
--  }
-+  if( nSavepoint>nCurrent && pPager->useJournal ){
-+    int ii;                                 /* Iterator variable */
-+    PagerSavepoint *aNew;                   /* New Pager.aSavepoint array */
- 
--  /* 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
-+    /* 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);
-   }
--  pagerFixMaplimit(pPager);
- 
-   return rc;
- }
- 
--
- /*
--** The caller must be holding a SHARED lock on the database file to call
--** this function.
-+** 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.
-+**
-+** 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.
- **
--** 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 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 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.
--*/
--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 */
-+** 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.
-+**
-+** 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( 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) );
-+  assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK );
-+  assert( iSavepoint>=0 || op==SAVEPOINT_ROLLBACK );
- 
--  if( !pPager->tempFile && !pPager->pWal ){
--    if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN;
-+  if( rc==SQLITE_OK && iSavepoint<pPager->nSavepoint ){
-+    int ii;            /* Iterator variable */
-+    int nNew;          /* Number of remaining savepoints after this op. */
- 
--    /* Close any rollback journal previously open */
--    sqlite3OsClose(pPager->jfd);
-+    /* 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;
- 
--    rc = pagerOpenWal(pPager);
--    if( rc==SQLITE_OK ){
--      pPager->journalMode = PAGER_JOURNALMODE_WAL;
--      pPager->eState = PAGER_OPEN;
-+    /* 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);
-     }
--  }else{
--    *pbOpen = 1;
-   }
- 
-   return rc;
- }
- 
- /*
--** This function is called to close the connection to the log file prior
--** to switching from WAL to rollback mode.
-+** Return the full pathname of the database file.
- **
--** 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.
-+** 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.
- */
--SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager){
--  int rc = SQLITE_OK;
-+SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager *pPager, int nullIfMemDb){
-+  return (nullIfMemDb && pPager->memDb) ? "" : pPager->zFilename;
-+}
- 
--  assert( pPager->journalMode==PAGER_JOURNALMODE_WAL );
-+/*
-+** Return the VFS structure for the pager.
-+*/
-+SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){
-+  return pPager->pVfs;
-+}
- 
--  /* 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 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;
- }
- 
--#endif /* !SQLITE_OMIT_WAL */
-+/*
-+** Return the full pathname of the journal file.
-+*/
-+SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager *pPager){
-+  return pPager->zJournal;
-+}
- 
--#ifdef SQLITE_ENABLE_ZIPVFS
- /*
--** 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.
-+** Return true if fsync() calls are disabled for this pager.  Return FALSE
-+** if fsync()s are executed normally.
- */
--SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){
--  assert( pPager->eState==PAGER_READER );
--  return sqlite3WalFramesize(pPager->pWal);
-+SQLITE_PRIVATE int sqlite3PagerNosync(Pager *pPager){
-+  return pPager->noSync;
- }
--#endif
- 
- #ifdef SQLITE_HAS_CODEC
- /*
--** 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.
-+** Set or retrieve the codec for this pager
- */
--SQLITE_PRIVATE void *sqlite3PagerCodec(PgHdr *pPg){
--  void *aData = 0;
--  CODEC2(pPg->pPager, pPg->pData, pPg->pgno, 6, return 0, aData);
--  return aData;
-+SQLITE_PRIVATE void sqlite3PagerSetCodec(
++SQLITE_PRIVATE void sqlite3pager_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);
- }
--#endif /* SQLITE_HAS_CODEC */
--
--#endif /* SQLITE_OMIT_DISKIO */
-+SQLITE_PRIVATE void *sqlite3PagerGetCodec(Pager *pPager){
-+  return pPager->pCodec;
++  sqlite3PagerSetCodec(pPager, xCodec, xCodecSizeChng, xCodecFree, pCodec); 
 +}
-+#endif
- 
--/************** End of pager.c ***********************************************/
--/************** Begin file wal.c *********************************************/
-+#ifndef SQLITE_OMIT_AUTOVACUUM
- /*
--** 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:
-+** Move the page pPg to location pgno in the file.
- **
--**      iKey = (P * 383) % HASHTABLE_NSLOT
-+** 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.
- **
--** 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.
-+** 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 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.
-+** 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).
- **
--** 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.  
-+** 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.
- **
--** 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.
-+** This function may return SQLITE_NOMEM or an IO error code if an error
-+** occurs. Otherwise, it returns SQLITE_OK.
- */
--#ifndef SQLITE_OMIT_WAL
-+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) );
-+
-+  /* 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;
-+  }
-+
-+  /* 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;
-+  }
-+
-+  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.
-+  */
-+  if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){
-+    needSyncPgno = pPg->pgno;
-+    assert( pPager->journalMode==PAGER_JOURNALMODE_OFF ||
-+            pageInJournal(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 = pager_lookup(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);
-+    }
-+  }
- 
--/*
--** Trace output macros
--*/
--#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
--SQLITE_PRIVATE int sqlite3WalTrace = 0;
--# define WALTRACE(X)  if(sqlite3WalTrace) sqlite3DebugPrintf X
--#else
--# define WALTRACE(X)
-+  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);
-+    sqlite3PagerUnref(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);
-+    sqlite3PagerUnref(pPgHdr);
-+  }
-+
-+  return SQLITE_OK;
-+}
- #endif
- 
- /*
--** The maximum (and only) versions of the wal and wal-index formats
--** that may be interpreted by this version of SQLite.
--**
--** 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 a pointer to the data for the specified page.
- */
--#define WAL_MAX_VERSION      3007000
--#define WALINDEX_MAX_VERSION 3007000
-+SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *pPg){
-+  assert( pPg->nRef>0 || pPg->pPager->memDb );
-+  return pPg->pData;
-+}
- 
- /*
--** Indices of various locking bytes.   WAL_NREADER is the number
--** of available reader locks and should be at least 3.
-+** Return a pointer to the Pager.nExtra bytes of "extra" space 
-+** allocated along with the specified page.
- */
--#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)
--
--
--/* Object declarations */
--typedef struct WalIndexHdr WalIndexHdr;
--typedef struct WalIterator WalIterator;
--typedef struct WalCkptInfo WalCkptInfo;
--
-+SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *pPg){
-+  return pPg->pExtra;
-+}
- 
- /*
--** 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.
-+** 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 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.  
-+** The returned value is either PAGER_LOCKINGMODE_NORMAL or
-+** PAGER_LOCKINGMODE_EXCLUSIVE, indicating the current (possibly updated)
-+** locking-mode.
- */
--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 */
--};
-+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;
++SQLITE_PRIVATE void sqlite3pager_sqlite3PagerSetError( Pager *pPager, int error) {
++  pPager->errCode = error;
 +}
- 
- /*
--** 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.
--**
--** 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.
-+** Set the journal-mode for this pager. Parameter eMode must be one of:
- **
--** 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.
-+**    PAGER_JOURNALMODE_DELETE
-+**    PAGER_JOURNALMODE_TRUNCATE
-+**    PAGER_JOURNALMODE_PERSIST
-+**    PAGER_JOURNALMODE_OFF
-+**    PAGER_JOURNALMODE_MEMORY
-+**    PAGER_JOURNALMODE_WAL
- **
--** 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 journalmode is set to the value specified if the change is allowed.
-+** The change may be disallowed for the following reasons:
- **
--** 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.
-+**   *  An in-memory database can only have its journal_mode set to _OFF
-+**      or _MEMORY.
- **
--** 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.
-+**   *  Temporary databases cannot have _WAL journalmode.
- **
--** We assume that 32-bit loads are atomic and so no locks are needed in
--** order to read from any aReadMark[] entries.
-+** The returned indicate the current (possibly updated) journal-mode.
- */
--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 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
- 
--/* 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)
- 
--/* Size of header before each frame in wal */
--#define WAL_FRAME_HDRSIZE 24
-+  /* 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 );
- 
--/* Size of write ahead log header, including checksum. */
--/* #define WAL_HDRSIZE 24 */
--#define WAL_HDRSIZE 32
-+  /* 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 );
- 
--/* 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
-+  /* 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;
-+    }
-+  }
- 
--/*
--** 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( 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 );
-+      }
-+    }
-+  }
 +
-+  /* Return the new journal mode */
-+  return (int)pPager->journalMode;
-+}
- 
- /*
--** An open write-ahead log file is represented by an instance of the
--** following object.
-+** Return the current journal mode.
- */
--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
--};
-+SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager *pPager){
-+  return (int)pPager->journalMode;
-+}
- 
- /*
--** Candidate values for Wal.exclusiveMode.
-+** 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.
- */
--#define WAL_NORMAL_MODE     0
--#define WAL_EXCLUSIVE_MODE  1     
--#define WAL_HEAPMEMORY_MODE 2
-+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;
-+}
- 
- /*
--** Possible values for WAL.readOnly
-+** Get/set the size-limit used for persistent journal files.
-+**
-+** Setting the size limit to -1 means no limit is enforced.
-+** An attempt to set a limit smaller than -1 is a no-op.
- */
--#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 i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){
-+  if( iLimit>=-1 ){
-+    pPager->journalSizeLimit = iLimit;
-+    sqlite3WalLimit(pPager->pWal, iLimit);
-+  }
-+  return pPager->journalSizeLimit;
-+}
- 
- /*
--** Each page of the wal-index mapping contains a hash-table made up of
--** an array of HASHTABLE_NSLOT elements of the following type.
-+** 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.
- */
--typedef u16 ht_slot;
-+SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){
-+  return &pPager->pBackup;
-+}
- 
-+#ifndef SQLITE_OMIT_VACUUM
- /*
--** 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()).
-+** Unless this is an in-memory or temporary database, clear the pager cache.
- */
--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 */
--};
-+SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *pPager){
-+  if( !MEMDB && pPager->tempFile==0 ) pager_reset(pPager);
-+}
 +#endif
++/* END SQLCIPHER */
++
  
-+#ifndef SQLITE_OMIT_WAL
- /*
--** 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.
-+** 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.
- **
--** 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.
-+** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART.
- */
--#define HASHTABLE_NPAGE_ONE  (HASHTABLE_NPAGE - (WALINDEX_HDR_SIZE/sizeof(u32)))
-+SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){
-+  int rc = SQLITE_OK;
-+  if( pPager->pWal ){
-+    rc = sqlite3WalCheckpoint(pPager->pWal, eMode,
-+        pPager->xBusyHandler, pPager->pBusyHandlerArg,
-+        pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
-+        pnLog, pnCkpt
-+    );
-+  }
-+  return rc;
-+}
- 
--/* The wal-index is divided into pages of WALINDEX_PGSZ bytes each. */
--#define WALINDEX_PGSZ   (                                         \
--    sizeof(ht_slot)*HASHTABLE_NSLOT + HASHTABLE_NPAGE*sizeof(u32) \
--)
-+SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager){
-+  return sqlite3WalCallback(pPager->pWal);
-+}
- 
- /*
--** 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.
-+** Return true if the underlying VFS for the given pager supports the
-+** primitives necessary for write-ahead logging.
- */
--static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
--  int rc = SQLITE_OK;
-+SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager){
-+  const sqlite3_io_methods *pMethods = pPager->fd->pMethods;
-+  return pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap);
-+}
- 
--  /* Enlarge the pWal->apWiData[] array if required */
--  if( pWal->nWiData<=iPage ){
--    int nByte = sizeof(u32*)*(iPage+1);
--    volatile u32 **apNew;
+ /************** End of pager.c ***********************************************/
+ /************** Begin file wal.c *********************************************/
+@@ -46046,3267 +49457,2596 @@
+   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;
@@ -64224,13 +3906,7 @@
 -    pWal->apWiData = apNew;
 -    pWal->nWiData = iPage+1;
 -  }
-+/*
-+** 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 */
- 
+-
 -  /* Request a pointer to the required page from the VFS */
 -  if( pWal->apWiData[iPage]==0 ){
 -    if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
@@ -64245,65 +3921,29 @@
 -        rc = SQLITE_OK;
 -      }
 -    }
-+  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);
-   }
- 
+-  }
+-
 -  *ppPage = pWal->apWiData[iPage];
 -  assert( iPage==0 || *ppPage || rc!=SQLITE_OK );
-   return rc;
- }
- 
- /*
+-  return rc;
+-}
+-
+-/*
 -** Return a pointer to the WalCkptInfo structure in the wal-index.
-+** 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 volatile WalCkptInfo *walCkptInfo(Wal *pWal){
 -  assert( pWal->nWiData>0 && pWal->apWiData[0] );
 -  return (volatile WalCkptInfo*)&(pWal->apWiData[0][sizeof(WalIndexHdr)/2]);
 -}
-+static int pagerOpenWal(Pager *pPager){
-+  int rc = SQLITE_OK;
- 
+-
 -/*
 -** 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];
-+  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;
- }
- 
+-}
+-
 -/*
 -** The argument to this macro must be of type u32. On a little-endian
 -** architecture, it returns the u32 value that results from interpreting
@@ -64315,148 +3955,65 @@
 -    (((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).
-+** The caller must be holding a SHARED lock on the database file to call
-+** this function.
- **
+-**
 -** The checksum is written back into aOut[] before returning.
-+** 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.
- **
+-**
 -** nByte must be a positive multiple of 8.
-+** 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 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 */
-+SQLITE_PRIVATE int sqlite3PagerOpenWal(
-+  Pager *pPager,                  /* Pager object */
-+  int *pbOpen                     /* OUT: Set to true if call is a no-op */
- ){
+-){
 -  u32 s1, s2;
 -  u32 *aData = (u32 *)a;
 -  u32 *aEnd = (u32 *)&a[nByte];
-+  int rc = SQLITE_OK;             /* Return code */
- 
+-
 -  if( aIn ){
 -    s1 = aIn[0];
 -    s2 = aIn[1];
 -  }else{
 -    s1 = s2 = 0;
 -  }
-+  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) );
- 
+-
 -  assert( nByte>=8 );
 -  assert( (nByte&0x00000007)==0 );
-+  if( !pPager->tempFile && !pPager->pWal ){
-+    if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN;
- 
+-
 -  if( nativeCksum ){
 -    do {
 -      s1 += *aData++ + s2;
 -      s2 += *aData++ + s1;
 -    }while( aData<aEnd );
-+    /* 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;
-+    }
-   }else{
+-  }else{
 -    do {
 -      s1 += BYTESWAP32(aData[0]) + s2;
 -      s2 += BYTESWAP32(aData[1]) + s1;
 -      aData += 2;
 -    }while( aData<aEnd );
-+    *pbOpen = 1;
-   }
- 
+-  }
+-
 -  aOut[0] = s1;
 -  aOut[1] = s2;
-+  return rc;
- }
- 
+-}
+-
 -static void walShmBarrier(Wal *pWal){
 -  if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){
 -    sqlite3OsShmBarrier(pWal->pDbFd);
-+/*
-+** 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.
-+*/
-+SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager){
-+  int rc = SQLITE_OK;
-+
-+  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);
-+    }
-+  }
-+    
-+  /* 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
- /*
+-  }
+-}
+-
+-/*
 -** Write the header information in pWal->hdr into the wal-index.
 -**
 -** The checksum on pWal->hdr is updated before it is written.
-+** 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 walIndexWriteHdr(Wal *pWal){
 -  volatile WalIndexHdr *aHdr = walIndexHdr(pWal);
 -  const int nCksum = offsetof(WalIndexHdr, aCksum);
@@ -64468,20 +4025,13 @@
 -  memcpy((void *)&aHdr[1], (void *)&pWal->hdr, sizeof(WalIndexHdr));
 -  walShmBarrier(pWal);
 -  memcpy((void *)&aHdr[0], (void *)&pWal->hdr, sizeof(WalIndexHdr));
-+SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){
-+  assert( pPager->eState==PAGER_READER );
-+  return sqlite3WalFramesize(pPager->pWal);
- }
-+#endif
- 
-+#ifdef SQLITE_HAS_CODEC
- /*
+-}
+-
+-/*
 -** 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:
-+** This function is called by the wal module when writing page content
-+** into the log file.
- **
+-**
 -**     0: Page number.
 -**     4: For commit records, the size of the database image in pages 
 -**        after the commit. For all other records, zero.
@@ -64489,9 +4039,7 @@
 -**    12: Salt-2 (copied from the wal-header)
 -**    16: Checksum-1.
 -**    20: Checksum-2.
-+** This function returns a pointer to a buffer containing the encrypted
-+** page content. If a malloc fails, this function may return NULL.
- */
+-*/
 -static void walEncodeFrame(
 -  Wal *pWal,                      /* The write-ahead log */
 -  u32 iPage,                      /* Database page number for frame */
@@ -64505,26 +4053,15 @@
 -  sqlite3Put4byte(&aFrame[0], iPage);
 -  sqlite3Put4byte(&aFrame[4], nTruncate);
 -  memcpy(&aFrame[8], pWal->hdr.aSalt, 8);
-+SQLITE_PRIVATE void *sqlite3PagerCodec(PgHdr *pPg){
-+  void *aData = 0;
-+  CODEC2(pPg->pPager, pPg->pData, pPg->pgno, 6, return 0, aData);
-+  return aData;
-+}
-+#endif /* SQLITE_HAS_CODEC */
- 
+-
 -  nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN);
 -  walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
 -  walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum);
-+#endif /* SQLITE_OMIT_DISKIO */
- 
+-
 -  sqlite3Put4byte(&aFrame[16], aCksum[0]);
 -  sqlite3Put4byte(&aFrame[20], aCksum[1]);
-+/* BEGIN SQLCIPHER */
-+#ifdef SQLITE_HAS_CODEC
-+SQLITE_PRIVATE void sqlite3pager_get_codec(Pager *pPager, void **ctx) {
-+  *ctx = pPager->pCodec;
- }
- 
+-}
+-
 -/*
 -** 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
@@ -64536,47 +4073,26 @@
 -  u32 *pnTruncate,                /* OUT: New db size (or 0 if not commit) */
 -  u8 *aData,                      /* Pointer to page data (for checksum) */
 -  u8 *aFrame                      /* Frame data */
-+SQLITE_PRIVATE int sqlite3pager_is_mj_pgno(Pager *pPager, Pgno pgno) {
-+  return (PAGER_MJ_PGNO(pPager) == pgno) ? 1 : 0;
-+}
-+
-+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
- ){
+-){
 -  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 );
-+  sqlite3PagerSetCodec(pPager, xCodec, xCodecSizeChng, xCodecFree, pCodec); 
-+}
- 
+-
 -  /* 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;
 -  }
-+SQLITE_PRIVATE void sqlite3pager_sqlite3PagerSetError( Pager *pPager, int error) {
-+  pPager->errCode = error;
-+}
- 
+-
 -  /* A frame is only valid if the page number is creater than zero.
 -  */
 -  pgno = sqlite3Get4byte(&aFrame[0]);
 -  if( pgno==0 ){
 -    return 0;
 -  }
-+#endif
-+/* END SQLCIPHER */
- 
+-
 -  /* 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 
@@ -64591,7 +4107,7 @@
 -    /* Checksum failed. */
 -    return 0;
 -  }
- 
+-
 -  /* If we reach this point, the frame is valid.  Return the page number
 -  ** and the new database size.
 -  */
@@ -64599,259 +4115,13 @@
 -  *pnTruncate = sqlite3Get4byte(&aFrame[4]);
 -  return 1;
 -}
-+/************** 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.
-+**
-+** 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.
-+*/
-+#ifndef SQLITE_OMIT_WAL
- 
- 
+-
+-
 -#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";
@@ -64868,30 +4138,14 @@
 -}
 -#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.
- */
+-*/
 -static int walLockShared(Wal *pWal, int lockIdx){
 -  int rc;
 -  if( pWal->exclusiveMode ) return SQLITE_OK;
@@ -64925,10 +4179,8 @@
 -  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.
@@ -64955,9 +4207,7 @@
 -**
 -** 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.
- */
+-*/
 -static int walHashGet(
 -  Wal *pWal,                      /* WAL handle */
 -  int iHash,                      /* Find the iHash'th table */
@@ -64970,17 +4220,11 @@
 -
 -  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)
- 
+-
 -  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)];
@@ -64995,11 +4239,7 @@
 -  }
 -  return rc;
 -}
-+/* Object declarations */
-+typedef struct WalIndexHdr WalIndexHdr;
-+typedef struct WalIterator WalIterator;
-+typedef struct WalCkptInfo WalCkptInfo;
- 
+-
 -/*
 -** Return the number of the wal-index page that contains the hash-table
 -** and page-number array that contain entries corresponding to WAL frame
@@ -65016,18 +4256,10 @@
 -  );
 -  return iHash;
 -}
- 
- /*
+-
+-/*
 -** 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 ){
@@ -65035,77 +4267,19 @@
 -  }
 -  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 */
-+};
- 
- /*
+-
+-/*
 -** 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.
- */
+-*/
 -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 */
@@ -65118,14 +4292,9 @@
 -  testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE-1 );
 -  testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE );
 -  testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE+1 );
-+struct WalCkptInfo {
-+  u32 nBackfill;                  /* Number of WAL frames backfilled into DB */
-+  u32 aReadMark[WAL_NREADER];     /* Reader marks */
-+};
-+#define READMARK_NOT_USED  0xffffffff
- 
+-
 -  if( pWal->hdr.mxFrame==0 ) return;
- 
+-
 -  /* 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.
@@ -65133,15 +4302,7 @@
 -  assert( pWal->nWiData>walFramePage(pWal->hdr.mxFrame) );
 -  assert( pWal->apWiData[walFramePage(pWal->hdr.mxFrame)] );
 -  walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &aHash, &aPgno, &iZero);
-+/* 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)
- 
+-
 -  /* Zero all hash-table entries that correspond to frame numbers greater
 -  ** than pWal->hdr.mxFrame.
 -  */
@@ -65158,9 +4319,7 @@
 -  */
 -  nByte = (int)((char *)aHash - (char *)&aPgno[iLimit+1]);
 -  memset((void *)&aPgno[iLimit+1], 0, nByte);
-+/* Size of header before each frame in wal */
-+#define WAL_FRAME_HDRSIZE 24
- 
+-
 -#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.
@@ -65177,28 +4336,12 @@
 -  }
 -#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
 -}
-+/* Size of write ahead log header, including checksum. */
-+/* #define WAL_HDRSIZE 24 */
-+#define WAL_HDRSIZE 32
- 
-+/* 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
- 
- /*
+-
+-
+-/*
 -** Set an entry in the wal-index that will map database page number
 -** pPage into WAL frame iFrame.
-+** 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.
- */
+-*/
 -static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){
 -  int rc;                         /* Return code */
 -  u32 iZero = 0;                  /* One less than frame number of aPgno[1] */
@@ -65214,10 +4357,7 @@
 -    int iKey;                     /* Hash table key */
 -    int idx;                      /* Value to write to hash-table slot */
 -    int nCollide;                 /* Number of hash collisions */
-+#define walFrameOffset(iFrame, szPage) (                               \
-+  WAL_HDRSIZE + ((iFrame)-1)*(i64)((szPage)+WAL_FRAME_HDRSIZE)         \
-+)
- 
+-
 -    idx = iFrame - iZero;
 -    assert( idx <= HASHTABLE_NSLOT/2 + 1 );
 -    
@@ -65228,37 +4368,7 @@
 -      int nByte = (int)((u8 *)&aHash[HASHTABLE_NSLOT] - (u8 *)&aPgno[1]);
 -      memset((void*)&aPgno[1], 0, nByte);
 -    }
-+/*
-+** An open write-ahead log file is represented by an instance of the
-+** following object.
-+*/
-+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
-+};
- 
+-
 -    /* 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). 
@@ -65269,13 +4379,7 @@
 -      walCleanupHash(pWal);
 -      assert( !aPgno[idx] );
 -    }
-+/*
-+** Candidate values for Wal.exclusiveMode.
-+*/
-+#define WAL_NORMAL_MODE     0
-+#define WAL_EXCLUSIVE_MODE  1     
-+#define WAL_HEAPMEMORY_MODE 2
- 
+-
 -    /* Write the aPgno[] array entry and the hash-table slot. */
 -    nCollide = idx;
 -    for(iKey=walHash(iPage); aHash[iKey]; iKey=walNextHash(iKey)){
@@ -65283,13 +4387,7 @@
 -    }
 -    aPgno[idx] = iPage;
 -    aHash[iKey] = (ht_slot)idx;
-+/*
-+** 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 */
- 
+-
 -#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.
@@ -65299,12 +4397,16 @@
 -      int nEntry = 0;  /* Number of entries in the hash table */
 -      for(i=0; i<HASHTABLE_NSLOT; i++){ if( aHash[i] ) nEntry++; }
 -      assert( nEntry==idx );
--    }
-+/*
-+** 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;
++    apNew = (volatile u32 **)sqlite3_realloc((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;
++  }
  
 -    /* Verify that the every entry in the mapping region is reachable
 -    ** via the hash table.  This turns out to be a really, really expensive
@@ -65318,78 +4420,47 @@
 -          if( aHash[iKey]==i ) break;
 -        }
 -        assert( aHash[iKey]==i );
--      }
--    }
++  /* 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;
+       }
+     }
 -#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
--  }
-+/*
-+** 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 */
-+};
+   }
  
-+/*
-+** 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 */
+-
++  *ppPage = pWal->apWiData[iPage];
++  assert( iPage==0 || *ppPage || rc!=SQLITE_OK );
+   return rc;
+ }
  
--  return rc;
--}
-+/* 
-+** 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.
++/*
++** Return a pointer to the WalCkptInfo structure in 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) \
-+)
++static volatile WalCkptInfo *walCkptInfo(Wal *pWal){
++  assert( pWal->nWiData>0 && pWal->apWiData[0] );
++  return (volatile WalCkptInfo*)&(pWal->apWiData[0][sizeof(WalIndexHdr)/2]);
++}
  
  /*
 -** Recover the wal-index by reading the write-ahead log file. 
-+** 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.
- **
+-**
 -** 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.
-+** 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.
++** Return a pointer to the WalIndexHdr structure in the wal-index.
  */
 -static int walIndexRecover(Wal *pWal){
 -  int rc;                         /* Return Code */
@@ -65397,7 +4468,11 @@
 -  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.
@@ -65415,27 +4490,47 @@
 -    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));
-+static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
-+  int rc = SQLITE_OK;
++/*
++** 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;
-+  /* 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;
-+    }
-+    memset((void*)&apNew[pWal->nWiData], 0,
-+           sizeof(u32*)*(iPage+1-pWal->nWiData));
-+    pWal->apWiData = apNew;
-+    pWal->nWiData = iPage+1;
++  if( aIn ){
++    s1 = aIn[0];
++    s2 = aIn[1];
++  }else{
++    s1 = s2 = 0;
    }
  
 -  if( nSize>WAL_HDRSIZE ){
@@ -65454,22 +4549,8 @@
 -    rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0);
 -    if( rc!=SQLITE_OK ){
 -      goto recovery_error;
-+  /* 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;
-+      }
-     }
-+  }
- 
+-    }
+-
 -    /* 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
@@ -65488,11 +4569,7 @@
 -    pWal->szPage = szPage;
 -    pWal->nCkpt = sqlite3Get4byte(&aBuf[12]);
 -    memcpy(&pWal->hdr.aSalt, &aBuf[16], 8);
-+  *ppPage = pWal->apWiData[iPage];
-+  assert( iPage==0 || *ppPage || rc!=SQLITE_OK );
-+  return rc;
-+}
- 
+-
 -    /* Verify that the WAL header checksum is correct */
 -    walChecksumBytes(pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN, 
 -        aBuf, WAL_HDRSIZE-2*4, 0, pWal->hdr.aFrameCksum
@@ -65502,14 +4579,7 @@
 -    ){
 -      goto finished;
 -    }
-+/*
-+** 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]);
-+}
- 
+-
 -    /* Verify that the version number on the WAL format is one that
 -    ** are able to understand */
 -    version = sqlite3Get4byte(&aBuf[4]);
@@ -65517,14 +4587,7 @@
 -      rc = SQLITE_CANTOPEN_BKPT;
 -      goto finished;
 -    }
-+/*
-+** 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];
-+}
- 
+-
 -    /* Malloc a buffer to read frames into. */
 -    szFrame = szPage + WAL_FRAME_HDRSIZE;
 -    aFrame = (u8 *)sqlite3_malloc(szFrame);
@@ -65533,43 +4596,13 @@
 -      goto recovery_error;
 -    }
 -    aData = &aFrame[WAL_FRAME_HDRSIZE];
-+/*
-+** 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) \
-+)
- 
+-
 -    /* 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 */
-+/*
-+** 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];
- 
+-
 -      /* Read and decode the next log frame. */
 -      iFrame++;
 -      rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset);
@@ -65578,13 +4611,7 @@
 -      if( !isValid ) break;
 -      rc = walIndexAppend(pWal, iFrame, pgno);
 -      if( rc!=SQLITE_OK ) break;
-+  if( aIn ){
-+    s1 = aIn[0];
-+    s2 = aIn[1];
-+  }else{
-+    s1 = s2 = 0;
-+  }
- 
+-
 -      /* If nTruncate is non-zero, this is a commit record. */
 -      if( nTruncate ){
 -        pWal->hdr.mxFrame = iFrame;
@@ -66505,6 +5532,12 @@
 +    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 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
@@ -66527,18 +5560,6 @@
 -      }else{
 -        goto walcheckpoint_out;
 -      }
-+    /* Read in the WAL header. */
-+    rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0);
-+    if( rc!=SQLITE_OK ){
-+      goto recovery_error;
-     }
--  }
- 
--  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 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
@@ -66552,15 +5573,18 @@
 +     || 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);
  
--    /* 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;
 +    /* Verify that the WAL header checksum is correct */
 +    walChecksumBytes(pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN, 
 +        aBuf, WAL_HDRSIZE-2*4, 0, pWal->hdr.aFrameCksum
@@ -66569,6 +5593,17 @@
 +     || pWal->hdr.aFrameCksum[1]!=sqlite3Get4byte(&aBuf[28])
 +    ){
 +      goto finished;
++    }
+ 
+-    /* Sync the WAL to disk */
+-    if( sync_flags ){
+-      rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
++    /* 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;
      }
  
 -    /* If the database may grow as a result of this checkpoint, hint
@@ -66580,14 +5615,6 @@
 -      if( rc==SQLITE_OK && nSize<nReq ){
 -        sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
 -      }
-+    /* 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);
@@ -67759,7 +6786,7 @@
 -  if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){
 -    walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
 -    pWal->writeLock = 0;
--    rc = SQLITE_BUSY;
+-    rc = SQLITE_BUSY_SNAPSHOT;
 +  mxSafeFrame = pWal->hdr.mxFrame;
 +  mxPage = pWal->hdr.nPage;
 +  for(i=1; i<WAL_NREADER; i++){
@@ -68078,19 +7105,13 @@
  
  /*
 -** 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 */
@@ -68104,10 +7125,45 @@
 -  if( rc ) return rc;
 -  /* Write the page data */
 -  rc = walWriteToLog(p, pData, p->szPage, iOffset+sizeof(aFrame));
+-  return rc;
+-}
+-
+-/* 
+-** Write a set of frames to the log. The caller must hold the write-lock
+-** on the log file (obtained using sqlite3WalBeginWriteTransaction()).
++** Close a connection to a log file.
+ */
+-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) */
++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;                         /* 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 */
+-
+-  assert( pList );
+-  assert( pWal->writeLock );
 +  int rc = SQLITE_OK;
 +  if( pWal ){
 +    int isDelete = 0;             /* True to unlink wal and wal-index files */
-+
+ 
+-  /* 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 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
@@ -68145,7 +7201,11 @@
 +        }
 +      }
 +    }
-+
+ 
+-#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"));
 +    walIndexClose(pWal, isDelete);
 +    sqlite3OsClose(pWal->pWalFd);
 +    if( isDelete ){
@@ -68156,13 +7216,17 @@
 +    WALTRACE(("WAL%p: closed\n", pWal));
 +    sqlite3_free((void *)pWal->apWiData);
 +    sqlite3_free(pWal);
-+  }
-   return rc;
- }
+   }
+-#endif
++  return rc;
++}
  
--/* 
--** Write a set of frames to the log. The caller must hold the write-lock
--** on the log file (obtained using sqlite3WalBeginWriteTransaction()).
+-  /* 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;
+-  }
 +/*
 +** Try to read the wal-index header.  Return 0 on success and 1 if
 +** there is a problem.
@@ -68179,73 +7243,12 @@
 +**
 +** If the checksum cannot be verified return non-zero. If the header
 +** is read successfully and the checksum verified, return zero.
- */
--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 */
++*/
 +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 );
-+  /* 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) );
-+  /* 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
-+  ** from the file. If this happens, return non-zero.
-+  **
-+  ** There are two copies of the header at the beginning of the wal-index.
-+  ** 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.
-+  */
-+  aHdr = walIndexHdr(pWal);
-+  memcpy(&h1, (void *)&aHdr[0], sizeof(h1));
-+  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( 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.
@@ -68254,7 +7257,9 @@
 -  if( iFrame==0 ){
 -    u8 aWalHdr[WAL_HDRSIZE];      /* Buffer to assemble wal-header in */
 -    u32 aCksum[2];                /* Checksum for wal-header */
--
++  /* The first page of the wal-index must be mapped at this point. */
++  assert( pWal->nWiData>0 && pWal->apWiData[0] );
+ 
 -    sqlite3Put4byte(&aWalHdr[0], (WAL_MAGIC | SQLITE_BIGENDIAN));
 -    sqlite3Put4byte(&aWalHdr[4], WAL_MAX_VERSION);
 -    sqlite3Put4byte(&aWalHdr[8], szPage);
@@ -68270,13 +7275,37 @@
 -    pWal->hdr.aFrameCksum[0] = aCksum[0];
 -    pWal->hdr.aFrameCksum[1] = aCksum[1];
 -    pWal->truncateOnCommit = 1;
--
++  /* 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
++  ** from the file. If this happens, return non-zero.
++  **
++  ** There are two copies of the header at the beginning of the wal-index.
++  ** 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.
++  */
++  aHdr = walIndexHdr(pWal);
++  memcpy(&h1, (void *)&aHdr[0], sizeof(h1));
++  walShmBarrier(pWal);
++  memcpy(&h2, (void *)&aHdr[1], sizeof(h2));
+ 
 -    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( memcmp(&h1, &h2, sizeof(h1))!=0 ){
++    return 1;   /* Dirty read */
++  }  
++  if( h1.isInit==0 ){
++    return 1;   /* Malformed header - probably all zeros */
++  }
++  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 */
++  }
+ 
 -    /* 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
@@ -69280,7 +8309,7 @@
 +  if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){
 +    walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
 +    pWal->writeLock = 0;
-+    rc = SQLITE_BUSY;
++    rc = SQLITE_BUSY_SNAPSHOT;
 +  }
 +
 +  return rc;
@@ -70059,14 +9088,19 @@
 -/*
 -** Potential values for BtCursor.eState.
 -**
--** CURSOR_VALID:
--**   Cursor points to a valid entry. getPayload() etc. may be called.
--**
 -** CURSOR_INVALID:
 -**   Cursor does not point to a valid entry. This can happen (for example) 
 -**   because the table is empty or because BtreeCursorFirst() has not been
 -**   called.
 -**
+-** CURSOR_VALID:
+-**   Cursor points to a valid entry. getPayload() etc. may be called.
+-**
+-** CURSOR_SKIPNEXT:
+-**   Cursor is valid except that the Cursor.skipNext field is non-zero
+-**   indicating that the next sqlite3BtreeNext() or sqlite3BtreePrevious()
+-**   operation should be a no-op.
+-**
 -** CURSOR_REQUIRESEEK:
 -**   The table that this cursor was opened on still exists, but has been 
 -**   modified since the cursor was last used. The cursor position is saved
@@ -70083,8 +9117,9 @@
 -*/
 -#define CURSOR_INVALID           0
 -#define CURSOR_VALID             1
--#define CURSOR_REQUIRESEEK       2
--#define CURSOR_FAULT             3
+-#define CURSOR_SKIPNEXT          2
+-#define CURSOR_REQUIRESEEK       3
+-#define CURSOR_FAULT             4
 +  /* Copy data from the log to the database file. */
 +  if( rc==SQLITE_OK ){
 +    if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
@@ -70334,7 +9369,7 @@
  #ifndef SQLITE_OMIT_SHARED_CACHE
  #if SQLITE_THREADSAFE
  
-@@ -88696,10 +91098,24 @@
+@@ -88995,10 +91735,24 @@
  */
  SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
    int rc = sqlite3_overload_function(db, "MATCH", 2);
@@ -70359,34 +9394,34 @@
  }
  
  /*
-@@ -93695,6 +96111,12 @@
+@@ -94082,6 +96836,12 @@
    sqlite3 *db = pParse->db;    /* The database connection */
    Db *pDb;                     /* The specific database being pragmaed */
    Vdbe *v = sqlite3GetVdbe(pParse);  /* Prepared statement */
 +/* BEGIN SQLCIPHER */
 +#ifdef SQLITE_HAS_CODEC
-+  extern int codec_pragma(sqlite3*, int, Parse *, const char *, const char *);
++  extern int sqlcipher_codec_pragma(sqlite3*, int, Parse *, const char *, const char *);
 +#endif
 +/* END SQLCIPHER */
 +
  
    if( v==0 ) return;
    sqlite3VdbeRunOnlyOnce(v);
-@@ -93755,6 +96177,13 @@
+@@ -94142,6 +96902,13 @@
      pParse->rc = rc;
    }else
                              
 +/* BEGIN SQLCIPHER */
 +#ifdef SQLITE_HAS_CODEC
-+  if(codec_pragma(db, iDb, pParse, zLeft, zRight)) { 
-+    /* codec_pragma executes internal */
++  if(sqlcipher_codec_pragma(db, iDb, pParse, zLeft, zRight)) { 
++    /* sqlcipher_codec_pragma executes internal */
 +  }else
 +  #endif
 +/* END SQLCIPHER */
   
  #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
    /*
-@@ -94348,60 +96777,6 @@
+@@ -94739,60 +97506,6 @@
  
  #ifndef SQLITE_OMIT_SCHEMA_PRAGMAS
    /*


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