]> rtime.felk.cvut.cz Git - l4.git/blobdiff - l4/pkg/sqlite/lib/contrib/sqlite3.c
update
[l4.git] / l4 / pkg / sqlite / lib / contrib / sqlite3.c
index f69816e2a65d0b1321041957580bf2984706c094..f7dabc6c7f7d02d1fdd21301682a23304a7e2605 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
 ** This file is an amalgamation of many separate C source files from SQLite
-** version 3.7.13.  By combining all the individual C code files into this 
+** version 3.7.15.  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
 **
 **     SQLITE_SYSTEM_MALLOC          // Use normal system malloc()
 **     SQLITE_WIN32_MALLOC           // Use Win32 native heap API
+**     SQLITE_ZERO_MALLOC            // Use a stub allocator that always fails
 **     SQLITE_MEMDEBUG               // Debugging version of system malloc()
 **
 ** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the
 ** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as
 ** the default.
 */
-#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)>1
-# error "At most one of the following compile-time configuration options\
- is allows: SQLITE_SYSTEM_MALLOC, SQLITE_WIN32_MALLOC, SQLITE_MEMDEBUG"
-#endif
-#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)==0
+#if defined(SQLITE_SYSTEM_MALLOC) \
+  + defined(SQLITE_WIN32_MALLOC) \
+  + defined(SQLITE_ZERO_MALLOC) \
+  + defined(SQLITE_MEMDEBUG)>1
+# error "Two or more of the following compile-time configuration options\
+ are defined but at most one is allowed:\
+ SQLITE_SYSTEM_MALLOC, SQLITE_WIN32_MALLOC, SQLITE_MEMDEBUG,\
+ SQLITE_ZERO_MALLOC"
+#endif
+#if defined(SQLITE_SYSTEM_MALLOC) \
+  + defined(SQLITE_WIN32_MALLOC) \
+  + defined(SQLITE_ZERO_MALLOC) \
+  + defined(SQLITE_MEMDEBUG)==0
 # define SQLITE_SYSTEM_MALLOC 1
 #endif
 
@@ -664,9 +673,9 @@ extern "C" {
 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
 ** [sqlite_version()] and [sqlite_source_id()].
 */
-#define SQLITE_VERSION        "3.7.13"
-#define SQLITE_VERSION_NUMBER 3007013
-#define SQLITE_SOURCE_ID      "2012-06-11 02:05:22 f5b5a13f7394dc143aa136f1d4faba6839eaa6dc"
+#define SQLITE_VERSION        "3.7.15"
+#define SQLITE_VERSION_NUMBER 3007015
+#define SQLITE_SOURCE_ID      "2012-12-12 13:36:53 cd0b37c52658bfdf992b1e3dc467bae1835a94ae"
 
 /*
 ** CAPI3REF: Run-Time Library Version Numbers
@@ -776,7 +785,8 @@ SQLITE_API int sqlite3_threadsafe(void);
 ** the opaque structure named "sqlite3".  It is useful to think of an sqlite3
 ** pointer as an object.  The [sqlite3_open()], [sqlite3_open16()], and
 ** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()]
-** is its destructor.  There are many other interfaces (such as
+** and [sqlite3_close_v2()] are its destructors.  There are many other
+** interfaces (such as
 ** [sqlite3_prepare_v2()], [sqlite3_create_function()], and
 ** [sqlite3_busy_timeout()] to name but three) that are methods on an
 ** sqlite3 object.
@@ -823,28 +833,46 @@ typedef sqlite_uint64 sqlite3_uint64;
 /*
 ** CAPI3REF: Closing A Database Connection
 **
-** ^The sqlite3_close() routine is the destructor for the [sqlite3] object.
-** ^Calls to sqlite3_close() return SQLITE_OK if the [sqlite3] object is
-** successfully destroyed and all associated resources are deallocated.
-**
-** Applications must [sqlite3_finalize | finalize] all [prepared statements]
-** and [sqlite3_blob_close | close] all [BLOB handles] associated with
-** the [sqlite3] object prior to attempting to close the object.  ^If
+** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors
+** for the [sqlite3] object.
+** ^Calls to sqlite3_close() and sqlite3_close_v2() return SQLITE_OK if
+** the [sqlite3] object is successfully destroyed and all associated
+** resources are deallocated.
+**
+** ^If the database connection is associated with unfinalized prepared
+** statements or unfinished sqlite3_backup objects then sqlite3_close()
+** will leave the database connection open and return [SQLITE_BUSY].
+** ^If sqlite3_close_v2() is called with unfinalized prepared statements
+** and unfinished sqlite3_backups, then the database connection becomes
+** an unusable "zombie" which will automatically be deallocated when the
+** last prepared statement is finalized or the last sqlite3_backup is
+** finished.  The sqlite3_close_v2() interface is intended for use with
+** host languages that are garbage collected, and where the order in which
+** destructors are called is arbitrary.
+**
+** Applications should [sqlite3_finalize | finalize] all [prepared statements],
+** [sqlite3_blob_close | close] all [BLOB handles], and 
+** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
+** with the [sqlite3] object prior to attempting to close the object.  ^If
 ** sqlite3_close() is called on a [database connection] that still has
-** outstanding [prepared statements] or [BLOB handles], then it returns
-** SQLITE_BUSY.
+** outstanding [prepared statements], [BLOB handles], and/or
+** [sqlite3_backup] objects then it returns SQLITE_OK but the deallocation
+** of resources is deferred until all [prepared statements], [BLOB handles],
+** and [sqlite3_backup] objects are also destroyed.
 **
-** ^If [sqlite3_close()] is invoked while a transaction is open,
+** ^If an [sqlite3] object is destroyed while a transaction is open,
 ** the transaction is automatically rolled back.
 **
-** The C parameter to [sqlite3_close(C)] must be either a NULL
+** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)]
+** must be either a NULL
 ** pointer or an [sqlite3] object pointer obtained
 ** from [sqlite3_open()], [sqlite3_open16()], or
 ** [sqlite3_open_v2()], and not previously closed.
-** ^Calling sqlite3_close() with a NULL pointer argument is a 
-** harmless no-op.
+** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer
+** argument is a harmless no-op.
 */
-SQLITE_API int sqlite3_close(sqlite3 *);
+SQLITE_API int sqlite3_close(sqlite3*);
+SQLITE_API int sqlite3_close_v2(sqlite3*);
 
 /*
 ** The type for a callback function.
@@ -1012,10 +1040,12 @@ SQLITE_API int sqlite3_exec(
 #define SQLITE_IOERR_SHMLOCK           (SQLITE_IOERR | (20<<8))
 #define SQLITE_IOERR_SHMMAP            (SQLITE_IOERR | (21<<8))
 #define SQLITE_IOERR_SEEK              (SQLITE_IOERR | (22<<8))
+#define SQLITE_IOERR_DELETE_NOENT      (SQLITE_IOERR | (23<<8))
 #define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
 #define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<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))
 #define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
 #define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
 #define SQLITE_READONLY_CANTLOCK       (SQLITE_READONLY | (2<<8))
@@ -1055,7 +1085,7 @@ SQLITE_API int sqlite3_exec(
 ** CAPI3REF: Device Characteristics
 **
 ** The xDeviceCharacteristics method of the [sqlite3_io_methods]
-** object returns an integer which is a vector of the these
+** object returns an integer which is a vector of these
 ** bit values expressing I/O characteristics of the mass storage
 ** device that holds the file that the [sqlite3_io_methods]
 ** refers to.
@@ -1393,6 +1423,26 @@ struct sqlite3_io_methods {
 ** compilation of the PRAGMA fails with an error.  ^The [SQLITE_FCNTL_PRAGMA]
 ** file control occurs at the beginning of pragma statement analysis and so
 ** it is able to override built-in [PRAGMA] statements.
+**
+** <li>[[SQLITE_FCNTL_BUSYHANDLER]]
+** ^This file-control may be invoked by SQLite on the database file handle
+** shortly after it is opened in order to provide a custom VFS with access
+** to the connections busy-handler callback. The argument is of type (void **)
+** - an array of two (void *) values. The first (void *) actually points
+** to a function of type (int (*)(void *)). In order to invoke the connections
+** busy-handler, this function should be invoked with the second (void *) in
+** the array as the only argument. If it returns non-zero, then the operation
+** should be retried. If it returns zero, the custom VFS should abandon the
+** current operation.
+**
+** <li>[[SQLITE_FCNTL_TEMPFILENAME]]
+** ^Application can invoke this file-control to have SQLite generate a
+** temporary filename using the same algorithm that is followed to generate
+** temporary filenames for TEMP tables and other internal uses.  The
+** argument should be a char** which will be filled with the filename
+** written into memory obtained from [sqlite3_malloc()].  The caller should
+** invoke [sqlite3_free()] on the result to avoid a memory leak.
+**
 ** </ul>
 */
 #define SQLITE_FCNTL_LOCKSTATE               1
@@ -1409,6 +1459,8 @@ struct sqlite3_io_methods {
 #define SQLITE_FCNTL_VFSNAME                12
 #define SQLITE_FCNTL_POWERSAFE_OVERWRITE    13
 #define SQLITE_FCNTL_PRAGMA                 14
+#define SQLITE_FCNTL_BUSYHANDLER            15
+#define SQLITE_FCNTL_TEMPFILENAME           16
 
 /*
 ** CAPI3REF: Mutex Handle
@@ -2105,11 +2157,39 @@ struct sqlite3_mem_methods {
 ** disabled. The default value may be changed by compiling with the
 ** [SQLITE_USE_URI] symbol defined.
 **
+** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
+** <dd> This option takes a single integer argument which is interpreted as
+** a boolean in order to enable or disable the use of covering indices for
+** full table scans in the query optimizer.  The default setting is determined
+** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
+** if that compile-time option is omitted.
+** The ability to disable the use of covering indices for full table scans
+** is because some incorrectly coded legacy applications might malfunction
+** malfunction when the optimization is enabled.  Providing the ability to
+** disable the optimization allows the older, buggy application code to work
+** without change even with newer versions of SQLite.
+**
 ** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]]
 ** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE
 ** <dd> These options are obsolete and should not be used by new code.
 ** They are retained for backwards compatibility but are now no-ops.
 ** </dl>
+**
+** [[SQLITE_CONFIG_SQLLOG]]
+** <dt>SQLITE_CONFIG_SQLLOG
+** <dd>This option is only available if sqlite is compiled with the
+** SQLITE_ENABLE_SQLLOG pre-processor macro defined. The first argument should
+** be a pointer to a function of type void(*)(void*,sqlite3*,const char*, int).
+** The second should be of type (void*). The callback is invoked by the library
+** in three separate circumstances, identified by the value passed as the
+** fourth parameter. If the fourth parameter is 0, then the database connection
+** passed as the second argument has just been opened. The third argument
+** points to a buffer containing the name of the main database file. If the
+** fourth parameter is 1, then the SQL statement that the third parameter
+** points to has just been executed. Or, if the fourth parameter is 2, then
+** the connection being passed as the second parameter is being closed. The
+** third parameter is passed NULL In this case.
+** </dl>
 */
 #define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
 #define SQLITE_CONFIG_MULTITHREAD   2  /* nil */
@@ -2130,6 +2210,8 @@ struct sqlite3_mem_methods {
 #define SQLITE_CONFIG_URI          17  /* int */
 #define SQLITE_CONFIG_PCACHE2      18  /* sqlite3_pcache_methods2* */
 #define SQLITE_CONFIG_GETPCACHE2   19  /* sqlite3_pcache_methods2* */
+#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20  /* int */
+#define SQLITE_CONFIG_SQLLOG       21  /* xSqllog, void* */
 
 /*
 ** CAPI3REF: Database Connection Configuration Options
@@ -3138,7 +3220,7 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
 **     an error)^. 
 **     ^If "ro" is specified, then the database is opened for read-only 
 **     access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the 
-**     third argument to sqlite3_prepare_v2(). ^If the mode option is set to 
+**     third argument to sqlite3_open_v2(). ^If the mode option is set to 
 **     "rw", then the database is opened for read-write (but not create) 
 **     access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had 
 **     been set. ^Value "rwc" is equivalent to setting both 
@@ -3205,6 +3287,12 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
 ** codepage is currently defined.  Filenames containing international
 ** characters must be converted to UTF-8 prior to passing them into
 ** sqlite3_open() or sqlite3_open_v2().
+**
+** <b>Note to Windows Runtime users:</b>  The temporary directory must be set
+** prior to calling sqlite3_open() or sqlite3_open_v2().  Otherwise, various
+** features that require the use of temporary files may fail.
+**
+** See also: [sqlite3_temp_directory]
 */
 SQLITE_API int sqlite3_open(
   const char *filename,   /* Database filename (UTF-8) */
@@ -3284,6 +3372,11 @@ SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int
 ** However, the error string might be overwritten or deallocated by
 ** subsequent calls to other SQLite interface functions.)^
 **
+** ^The sqlite3_errstr() interface returns the English-language text
+** that describes the [result code], as UTF-8.
+** ^(Memory to hold the error message string is managed internally
+** and must not be freed by the application)^.
+**
 ** When the serialized [threading mode] is in use, it might be the
 ** case that a second error occurs on a separate thread in between
 ** the time of the first error and the call to these interfaces.
@@ -3302,6 +3395,7 @@ SQLITE_API int sqlite3_errcode(sqlite3 *db);
 SQLITE_API int sqlite3_extended_errcode(sqlite3 *db);
 SQLITE_API const char *sqlite3_errmsg(sqlite3*);
 SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
+SQLITE_API const char *sqlite3_errstr(int);
 
 /*
 ** CAPI3REF: SQL Statement Object
@@ -3697,8 +3791,11 @@ typedef struct sqlite3_context sqlite3_context;
 ** ^(In those routines that have a fourth argument, its value is the
 ** number of bytes in the parameter.  To be clear: the value is the
 ** number of <u>bytes</u> in the value, not the number of characters.)^
-** ^If the fourth parameter is negative, the length of the string is
+** ^If the fourth parameter to sqlite3_bind_text() or sqlite3_bind_text16()
+** is negative, then the length of the string is
 ** the number of bytes up to the first zero terminator.
+** If the fourth parameter to sqlite3_bind_blob() is negative, then
+** the behavior is undefined.
 ** If a non-negative fourth parameter is provided to sqlite3_bind_text()
 ** or sqlite3_bind_text16() then that parameter must be the byte offset
 ** where the NUL terminator would occur assuming the string were NUL
@@ -4695,11 +4792,11 @@ typedef void (*sqlite3_destructor_type)(void*);
 ** the error code is SQLITE_ERROR.  ^A subsequent call to sqlite3_result_error()
 ** or sqlite3_result_error16() resets the error code to SQLITE_ERROR.
 **
-** ^The sqlite3_result_toobig() interface causes SQLite to throw an error
-** indicating that a string or BLOB is too long to represent.
+** ^The sqlite3_result_error_toobig() interface causes SQLite to throw an
+** error indicating that a string or BLOB is too long to represent.
 **
-** ^The sqlite3_result_nomem() interface causes SQLite to throw an error
-** indicating that a memory allocation failed.
+** ^The sqlite3_result_error_nomem() interface causes SQLite to throw an
+** error indicating that a memory allocation failed.
 **
 ** ^The sqlite3_result_int() interface sets the return value
 ** of the application-defined function to be the 32-bit signed integer
@@ -5006,6 +5103,21 @@ SQLITE_API int sqlite3_sleep(int);
 ** Hence, if this variable is modified directly, either it should be
 ** made NULL or made to point to memory obtained from [sqlite3_malloc]
 ** or else the use of the [temp_store_directory pragma] should be avoided.
+**
+** <b>Note to Windows Runtime users:</b>  The temporary directory must be set
+** prior to calling [sqlite3_open] or [sqlite3_open_v2].  Otherwise, various
+** features that require the use of temporary files may fail.  Here is an
+** example of how to do this using C++ with the Windows Runtime:
+**
+** <blockquote><pre>
+** LPCWSTR zPath = Windows::Storage::ApplicationData::Current->
+** &nbsp;     TemporaryFolder->Path->Data();
+** char zPathBuf&#91;MAX_PATH + 1&#93;;
+** memset(zPathBuf, 0, sizeof(zPathBuf));
+** WideCharToMultiByte(CP_UTF8, 0, zPath, -1, zPathBuf, sizeof(zPathBuf),
+** &nbsp;     NULL, NULL);
+** sqlite3_temp_directory = sqlite3_mprintf("%s", zPathBuf);
+** </pre></blockquote>
 */
 SQLITE_API char *sqlite3_temp_directory;
 
@@ -5246,6 +5358,9 @@ SQLITE_API void *sqlite3_update_hook(
 ** future releases of SQLite.  Applications that care about shared
 ** cache setting should set it explicitly.
 **
+** This interface is threadsafe on processors where writing a
+** 32-bit integer is atomic.
+**
 ** See Also:  [SQLite Shared-Cache Mode]
 */
 SQLITE_API int sqlite3_enable_shared_cache(int);
@@ -6051,7 +6166,6 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
 ** implementations are available in the SQLite core:
 **
 ** <ul>
-** <li>   SQLITE_MUTEX_OS2
 ** <li>   SQLITE_MUTEX_PTHREADS
 ** <li>   SQLITE_MUTEX_W32
 ** <li>   SQLITE_MUTEX_NOOP
@@ -6059,9 +6173,9 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
 **
 ** ^The SQLITE_MUTEX_NOOP implementation is a set of routines
 ** that does no real locking and is appropriate for use in
-** a single-threaded application.  ^The SQLITE_MUTEX_OS2,
-** SQLITE_MUTEX_PTHREADS, and SQLITE_MUTEX_W32 implementations
-** are appropriate for use on OS/2, Unix, and Windows.
+** a single-threaded application.  ^The SQLITE_MUTEX_PTHREADS and
+** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix
+** and Windows.
 **
 ** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
 ** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex
@@ -8212,6 +8326,7 @@ typedef struct Parse Parse;
 typedef struct RowSet RowSet;
 typedef struct Savepoint Savepoint;
 typedef struct Select Select;
+typedef struct SelectDest SelectDest;
 typedef struct SrcList SrcList;
 typedef struct StrAccum StrAccum;
 typedef struct Table Table;
@@ -8308,6 +8423,9 @@ SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree*,int);
 SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree*);
 SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree*,int);
 SQLITE_PRIVATE int sqlite3BtreeGetReserve(Btree*);
+#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_DEBUG)
+SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p);
+#endif
 SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int);
 SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *);
 SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int);
@@ -8351,6 +8469,8 @@ SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree*, int);
 SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue);
 SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
 
+SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p);
+
 /*
 ** The second parameter to sqlite3BtreeGetMeta or sqlite3BtreeUpdateMeta
 ** should be one of the following values. The integer values are assigned 
@@ -8372,6 +8492,12 @@ SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
 #define BTREE_USER_VERSION        6
 #define BTREE_INCR_VACUUM         7
 
+/*
+** Values that may be OR'd together to form the second argument of an
+** sqlite3BtreeCursorHints() call.
+*/
+#define BTREE_BULKLOAD 0x00000001
+
 SQLITE_PRIVATE int sqlite3BtreeCursor(
   Btree*,                              /* BTree containing table to open */
   int iTable,                          /* Index of root page */
@@ -8415,8 +8541,8 @@ SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*);
 SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
 SQLITE_PRIVATE void sqlite3BtreeCacheOverflow(BtCursor *);
 SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *);
-
 SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
+SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask);
 
 #ifndef NDEBUG
 SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*);
@@ -8812,7 +8938,7 @@ typedef struct VdbeOpList VdbeOpList;
 #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, 0x24, 0x24,\
+/*   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,\
@@ -8859,7 +8985,7 @@ SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
 SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*);
 SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*);
 SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*);
-SQLITE_PRIVATE void sqlite3VdbeDeleteObject(sqlite3*,Vdbe*);
+SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3*,Vdbe*);
 SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,Parse*);
 SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*);
 SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int);
@@ -9049,11 +9175,14 @@ SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int n);
 SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint);
 SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager);
 
-SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int, int*, int*);
-SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager);
-SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager);
-SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
-SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager);
+#ifndef SQLITE_OMIT_WAL
+SQLITE_PRIVATE   int sqlite3PagerCheckpoint(Pager *pPager, int, int*, int*);
+SQLITE_PRIVATE   int sqlite3PagerWalSupported(Pager *pPager);
+SQLITE_PRIVATE   int sqlite3PagerWalCallback(Pager *pPager);
+SQLITE_PRIVATE   int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
+SQLITE_PRIVATE   int sqlite3PagerCloseWal(Pager *pPager);
+#endif
+
 #ifdef SQLITE_ENABLE_ZIPVFS
 SQLITE_PRIVATE   int sqlite3PagerWalFramesize(Pager *pPager);
 #endif
@@ -9071,6 +9200,7 @@ SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*);
 SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*);
 SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *);
 SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *);
+SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *);
 
 /* Functions used to truncate the database file. */
 SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno);
@@ -9290,7 +9420,7 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void);
 /*
 ** Figure out if we are dealing with Unix, Windows, or some other
 ** operating system.  After the following block of preprocess macros,
-** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, SQLITE_OS_OS2, and SQLITE_OS_OTHER 
+** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, and SQLITE_OS_OTHER 
 ** will defined to either 1 or 0.  One of the four will be 1.  The other 
 ** three will be 0.
 */
@@ -9300,8 +9430,6 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void);
 #   define SQLITE_OS_UNIX 0
 #   undef SQLITE_OS_WIN
 #   define SQLITE_OS_WIN 0
-#   undef SQLITE_OS_OS2
-#   define SQLITE_OS_OS2 0
 # else
 #   undef SQLITE_OS_OTHER
 # endif
@@ -9312,19 +9440,12 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void);
 #   if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
 #     define SQLITE_OS_WIN 1
 #     define SQLITE_OS_UNIX 0
-#     define SQLITE_OS_OS2 0
-#   elif defined(__EMX__) || defined(_OS2) || defined(OS2) || defined(_OS2_) || defined(__OS2__)
-#     define SQLITE_OS_WIN 0
-#     define SQLITE_OS_UNIX 0
-#     define SQLITE_OS_OS2 1
 #   else
 #     define SQLITE_OS_WIN 0
 #     define SQLITE_OS_UNIX 1
-#     define SQLITE_OS_OS2 0
 #  endif
 # else
 #  define SQLITE_OS_UNIX 0
-#  define SQLITE_OS_OS2 0
 # endif
 #else
 # ifndef SQLITE_OS_WIN
@@ -9336,21 +9457,6 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void);
 # include <windows.h>
 #endif
 
-#if SQLITE_OS_OS2
-# if (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 3) && defined(OS2_HIGH_MEMORY)
-#  include <os2safe.h> /* has to be included before os2.h for linking to work */
-# endif
-# define INCL_DOSDATETIME
-# define INCL_DOSFILEMGR
-# define INCL_DOSERRORS
-# define INCL_DOSMISC
-# define INCL_DOSPROCESS
-# define INCL_DOSMODULEMGR
-# define INCL_DOSSEMAPHORES
-# include <os2.h>
-# include <uconv.h>
-#endif
-
 /*
 ** Determine if we are dealing with Windows NT.
 **
@@ -9383,8 +9489,8 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void);
 #endif
 
 /*
-** Determine if we are dealing with WindowsRT (Metro) as this has a different and
-** incompatible API from win32.
+** Determine if we are dealing with WinRT, which provides only a subset of
+** the full Win32 API.
 */
 #if !defined(SQLITE_OS_WINRT)
 # define SQLITE_OS_WINRT 0
@@ -9620,8 +9726,6 @@ SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *);
 **   SQLITE_MUTEX_PTHREADS     For multi-threaded applications on Unix.
 **
 **   SQLITE_MUTEX_W32          For multi-threaded applications on Win32.
-**
-**   SQLITE_MUTEX_OS2          For multi-threaded applications on OS/2.
 */
 #if !SQLITE_THREADSAFE
 # define SQLITE_MUTEX_OMIT
@@ -9631,8 +9735,6 @@ SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *);
 #    define SQLITE_MUTEX_PTHREADS
 #  elif SQLITE_OS_WIN
 #    define SQLITE_MUTEX_W32
-#  elif SQLITE_OS_OS2
-#    define SQLITE_MUTEX_OS2
 #  else
 #    define SQLITE_MUTEX_NOOP
 #  endif
@@ -9796,6 +9898,7 @@ struct sqlite3 {
   unsigned int openFlags;       /* Flags passed to sqlite3_vfs.xOpen() */
   int errCode;                  /* Most recent error code (SQLITE_*) */
   int errMask;                  /* & result codes with this before returning */
+  u16 dbOptFlags;               /* Flags to enable/disable optimizations */
   u8 autoCommit;                /* The auto-commit flag. */
   u8 temp_store;                /* 1: file 2: memory 0: default */
   u8 mallocFailed;              /* True if we have seen a malloc failure */
@@ -9900,48 +10003,59 @@ struct sqlite3 {
 /*
 ** Possible values for the sqlite3.flags.
 */
-#define SQLITE_VdbeTrace      0x00000100  /* True to trace VDBE execution */
-#define SQLITE_InternChanges  0x00000200  /* Uncommitted Hash table changes */
-#define SQLITE_FullColNames   0x00000400  /* Show full column names on SELECT */
-#define SQLITE_ShortColNames  0x00000800  /* Show short columns names */
-#define SQLITE_CountRows      0x00001000  /* Count rows changed by INSERT, */
+#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, */
                                           /*   DELETE, or UPDATE and return */
                                           /*   the count using a callback. */
-#define SQLITE_NullCallback   0x00002000  /* Invoke the callback once if the */
+#define SQLITE_NullCallback   0x00000020  /* Invoke the callback once if the */
                                           /*   result set is empty */
-#define SQLITE_SqlTrace       0x00004000  /* Debug print SQL as it executes */
-#define SQLITE_VdbeListing    0x00008000  /* Debug listings of VDBE programs */
-#define SQLITE_WriteSchema    0x00010000  /* OK to update SQLITE_MASTER */
-                         /*   0x00020000  Unused */
-#define SQLITE_IgnoreChecks   0x00040000  /* Do not enforce check constraints */
-#define SQLITE_ReadUncommitted 0x0080000  /* For shared-cache mode */
-#define SQLITE_LegacyFileFmt  0x00100000  /* Create new databases in format 1 */
-#define SQLITE_FullFSync      0x00200000  /* Use full fsync on the backend */
-#define SQLITE_CkptFullFSync  0x00400000  /* Use full fsync for checkpoint */
-#define SQLITE_RecoveryMode   0x00800000  /* Ignore schema errors */
-#define SQLITE_ReverseOrder   0x01000000  /* Reverse unordered SELECTs */
-#define SQLITE_RecTriggers    0x02000000  /* Enable recursive triggers */
-#define SQLITE_ForeignKeys    0x04000000  /* Enforce foreign key constraints  */
-#define SQLITE_AutoIndex      0x08000000  /* Enable automatic indexes */
-#define SQLITE_PreferBuiltin  0x10000000  /* Preference to built-in funcs */
-#define SQLITE_LoadExtension  0x20000000  /* Enable load_extension */
-#define SQLITE_EnableTrigger  0x40000000  /* True to enable triggers */
-
-/*
-** Bits of the sqlite3.flags field that are used by the
-** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface.
-** These must be the low-order bits of the flags field.
-*/
-#define SQLITE_QueryFlattener 0x01        /* Disable query flattening */
-#define SQLITE_ColumnCache    0x02        /* Disable the column cache */
-#define SQLITE_IndexSort      0x04        /* Disable indexes for sorting */
-#define SQLITE_IndexSearch    0x08        /* Disable indexes for searching */
-#define SQLITE_IndexCover     0x10        /* Disable index covering table */
-#define SQLITE_GroupByOrder   0x20        /* Disable GROUPBY cover of ORDERBY */
-#define SQLITE_FactorOutConst 0x40        /* Disable factoring out constants */
-#define SQLITE_IdxRealAsInt   0x80        /* Store REAL as INT in indices */
-#define SQLITE_DistinctOpt    0x80        /* DISTINCT using indexes */
-#define SQLITE_OptMask        0xff        /* Mask of all disablable opts */
+#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 */
+                         /*   0x00000200  Unused */
+#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 */
+
+/*
+** Bits of the sqlite3.dbOptFlags field that are used by the
+** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
+** selectively disable various optimizations.
+*/
+#define SQLITE_QueryFlattener 0x0001   /* Query flattening */
+#define SQLITE_ColumnCache    0x0002   /* Column cache */
+#define SQLITE_GroupByOrder   0x0004   /* GROUPBY cover of ORDERBY */
+#define SQLITE_FactorOutConst 0x0008   /* Constant factoring */
+#define SQLITE_IdxRealAsInt   0x0010   /* Store REAL as INT in indices */
+#define SQLITE_DistinctOpt    0x0020   /* DISTINCT using indexes */
+#define SQLITE_CoverIdxScan   0x0040   /* Covering index scans */
+#define SQLITE_OrderByIdxJoin 0x0080   /* ORDER BY of joins via index */
+#define SQLITE_SubqCoroutine  0x0100   /* Evaluate subqueries as coroutines */
+#define SQLITE_AllOpts        0xffff   /* All optimizations */
+
+/*
+** Macros for testing whether or not optimizations are enabled or disabled.
+*/
+#ifndef SQLITE_OMIT_BUILTIN_TEST
+#define OptimizationDisabled(db, mask)  (((db)->dbOptFlags&(mask))!=0)
+#define OptimizationEnabled(db, mask)   (((db)->dbOptFlags&(mask))==0)
+#else
+#define OptimizationDisabled(db, mask)  0
+#define OptimizationEnabled(db, mask)   1
+#endif
 
 /*
 ** Possible values for the sqlite.magic field.
@@ -9953,6 +10067,7 @@ struct sqlite3 {
 #define SQLITE_MAGIC_SICK     0x4b771290  /* Error and awaiting close */
 #define SQLITE_MAGIC_BUSY     0xf03b7906  /* Database currently in use */
 #define SQLITE_MAGIC_ERROR    0xb5357930  /* An SQLITE_MISUSE error occurred */
+#define SQLITE_MAGIC_ZOMBIE   0x64cffc7f  /* Close with last statement close */
 
 /*
 ** Each SQL function is defined by an instance of the following
@@ -10091,32 +10206,22 @@ struct Column {
   char *zDflt;     /* Original text of the default value */
   char *zType;     /* Data type for this column */
   char *zColl;     /* Collating sequence.  If NULL, use the default */
-  u8 notNull;      /* True if there is a NOT NULL constraint */
-  u8 isPrimKey;    /* True if this column is part of the PRIMARY KEY */
+  u8 notNull;      /* An OE_ code for handling a NOT NULL constraint */
   char affinity;   /* One of the SQLITE_AFF_... values */
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-  u8 isHidden;     /* True if this column is 'hidden' */
-#endif
+  u16 colFlags;    /* Boolean properties.  See COLFLAG_ defines below */
 };
 
+/* Allowed values for Column.colFlags:
+*/
+#define COLFLAG_PRIMKEY  0x0001    /* Column is part of the primary key */
+#define COLFLAG_HIDDEN   0x0002    /* A hidden column in a virtual table */
+
 /*
 ** A "Collating Sequence" is defined by an instance of the following
 ** structure. Conceptually, a collating sequence consists of a name and
 ** a comparison routine that defines the order of that sequence.
 **
-** There may two separate implementations of the collation function, one
-** that processes text in UTF-8 encoding (CollSeq.xCmp) and another that
-** processes text encoded in UTF-16 (CollSeq.xCmp16), using the machine
-** native byte order. When a collation sequence is invoked, SQLite selects
-** the version that will require the least expensive encoding
-** translations, if any.
-**
-** The CollSeq.pUser member variable is an extra parameter that passed in
-** as the first argument to the UTF-8 comparison function, xCmp.
-** CollSeq.pUser16 is the equivalent for the UTF-16 comparison function,
-** xCmp16.
-**
-** If both CollSeq.xCmp and CollSeq.xCmp16 are NULL, it means that the
+** If CollSeq.xCmp is NULL, it means that the
 ** collating sequence is undefined.  Indices built on an undefined
 ** collating sequence may not be read or written.
 */
@@ -10254,28 +10359,28 @@ struct VTable {
 */
 struct Table {
   char *zName;         /* Name of the table or view */
-  int iPKey;           /* If not negative, use aCol[iPKey] as the primary key */
-  int nCol;            /* Number of columns in this table */
   Column *aCol;        /* Information about each column */
   Index *pIndex;       /* List of SQL indexes on this table. */
-  int tnum;            /* Root BTree node for this table (see note above) */
-  tRowcnt nRowEst;     /* Estimated rows in table - from sqlite_stat1 table */
   Select *pSelect;     /* NULL for tables.  Points to definition if a view. */
-  u16 nRef;            /* Number of pointers to this Table */
-  u8 tabFlags;         /* Mask of TF_* values */
-  u8 keyConf;          /* What to do in case of uniqueness conflict on iPKey */
   FKey *pFKey;         /* Linked list of all foreign keys in this table */
   char *zColAff;       /* String defining the affinity of each column */
 #ifndef SQLITE_OMIT_CHECK
   ExprList *pCheck;    /* All CHECK constraints */
 #endif
+  tRowcnt nRowEst;     /* Estimated rows in table - from sqlite_stat1 table */
+  int tnum;            /* Root BTree node for this table (see note above) */
+  i16 iPKey;           /* If not negative, use aCol[iPKey] as the primary key */
+  i16 nCol;            /* Number of columns in this table */
+  u16 nRef;            /* Number of pointers to this Table */
+  u8 tabFlags;         /* Mask of TF_* values */
+  u8 keyConf;          /* What to do in case of uniqueness conflict on iPKey */
 #ifndef SQLITE_OMIT_ALTERTABLE
   int addColOffset;    /* Offset in CREATE TABLE stmt to add a new column */
 #endif
 #ifndef SQLITE_OMIT_VIRTUALTABLE
-  VTable *pVTable;     /* List of VTable objects. */
   int nModuleArg;      /* Number of arguments to the module */
   char **azModuleArg;  /* Text of all module args. [0] is module name */
+  VTable *pVTable;     /* List of VTable objects. */
 #endif
   Trigger *pTrigger;   /* List of triggers stored in pSchema */
   Schema *pSchema;     /* Schema that contains this table */
@@ -10299,7 +10404,7 @@ struct Table {
 */
 #ifndef SQLITE_OMIT_VIRTUALTABLE
 #  define IsVirtual(X)      (((X)->tabFlags & TF_Virtual)!=0)
-#  define IsHiddenColumn(X) ((X)->isHidden)
+#  define IsHiddenColumn(X) (((X)->colFlags & COLFLAG_HIDDEN)!=0)
 #else
 #  define IsVirtual(X)      0
 #  define IsHiddenColumn(X) 0
@@ -10644,13 +10749,15 @@ struct Expr {
     ExprList *pList;     /* Function arguments or in "<expr> IN (<expr-list)" */
     Select *pSelect;     /* Used for sub-selects and "<expr> IN (<select>)" */
   } x;
-  CollSeq *pColl;        /* The collation type of the column or 0 */
 
   /* If the EP_Reduced flag is set in the Expr.flags mask, then no
   ** space is allocated for the fields below this point. An attempt to
   ** access them will result in a segfault or malfunction.
   *********************************************************************/
 
+#if SQLITE_MAX_EXPR_DEPTH>0
+  int nHeight;           /* Height of the tree headed by this node */
+#endif
   int iTable;            /* TK_COLUMN: cursor number of table holding column
                          ** TK_REGISTER: register number
                          ** TK_TRIGGER: 1 -> new, 0 -> old */
@@ -10659,13 +10766,11 @@ struct Expr {
   i16 iAgg;              /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
   i16 iRightJoinTable;   /* If EP_FromJoin, the right table of the join */
   u8 flags2;             /* Second set of flags.  EP2_... */
-  u8 op2;                /* If a TK_REGISTER, the original value of Expr.op */
-                         /* If TK_COLUMN, the value of p5 for OP_Column */
+  u8 op2;                /* TK_REGISTER: original value of Expr.op
+                         ** TK_COLUMN: the value of p5 for OP_Column
+                         ** TK_AGG_FUNCTION: nesting depth */
   AggInfo *pAggInfo;     /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
   Table *pTab;           /* Table for TK_COLUMN expressions. */
-#if SQLITE_MAX_EXPR_DEPTH>0
-  int nHeight;           /* Height of the tree headed by this node */
-#endif
 };
 
 /*
@@ -10679,7 +10784,7 @@ struct Expr {
 #define EP_VarSelect  0x0020  /* pSelect is correlated, not constant */
 #define EP_DblQuoted  0x0040  /* token.z was originally in "..." */
 #define EP_InfixFunc  0x0080  /* True for an infix function: LIKE, GLOB, etc */
-#define EP_ExpCollate 0x0100  /* Collating sequence specified explicitly */
+#define EP_Collate    0x0100  /* Tree contains a TK_COLLATE opeartor */
 #define EP_FixedDest  0x0200  /* Result needed in a specific register */
 #define EP_IntValue   0x0400  /* Integer value contained in u.iValue */
 #define EP_xIsSelect  0x0800  /* x.pSelect is valid (otherwise x.pList is) */
@@ -10823,6 +10928,7 @@ struct SrcList {
   i16 nSrc;        /* Number of tables or subqueries in the FROM clause */
   i16 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 */
     char *zName;      /* Name of the table */
     char *zAlias;     /* The "B" part of a "A AS B" phrase.  zName is the "A" */
@@ -10831,8 +10937,9 @@ struct SrcList {
     int addrFillSub;  /* Address of subroutine to manifest a subquery */
     int regReturn;    /* Register holding return address of addrFillSub */
     u8 jointype;      /* Type of join between this able and the previous */
-    u8 notIndexed;    /* True if there is a NOT INDEXED clause */
-    u8 isCorrelated;  /* True if sub-query is correlated */
+    unsigned notIndexed :1;    /* True if there is a NOT INDEXED clause */
+    unsigned isCorrelated :1;  /* True if sub-query is correlated */
+    unsigned viaCoroutine :1;  /* Implemented as a co-routine */
 #ifndef SQLITE_OMIT_EXPLAIN
     u8 iSelectId;     /* If pSelect!=0, the id of the sub-select in EQP */
 #endif
@@ -10873,7 +10980,8 @@ struct SrcList {
 */
 struct WherePlan {
   u32 wsFlags;                   /* WHERE_* flags that describe the strategy */
-  u32 nEq;                       /* Number of == constraints */
+  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 */
@@ -10885,7 +10993,7 @@ struct WherePlan {
 /*
 ** 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 the the where.c module and should not be
+** 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
@@ -10915,7 +11023,9 @@ struct WhereLevel {
         int addrInTop;         /* Top of the IN loop */
       } *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
@@ -10948,24 +11058,28 @@ struct WhereLevel {
 ** into the second half to give some continuity.
 */
 struct WhereInfo {
-  Parse *pParse;       /* Parsing and code generating context */
-  u16 wctrlFlags;      /* Flags originally passed to sqlite3WhereBegin() */
-  u8 okOnePass;        /* Ok to use one-pass algorithm for UPDATE or DELETE */
-  u8 untestedTerms;    /* Not all WHERE terms resolved by outer loop */
-  u8 eDistinct;
-  SrcList *pTabList;             /* List of tables in the join */
-  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 */
+  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 */
 };
 
-#define WHERE_DISTINCT_UNIQUE 1
-#define WHERE_DISTINCT_ORDERED 2
+/* 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 */
+#define WHERE_DISTINCT_UNORDERED 3  /* Duplicates are scattered */
 
 /*
 ** A NameContext defines a context in which to resolve table and column
@@ -11024,13 +11138,12 @@ struct NameContext {
 ** as the OP_OpenEphm instruction is coded because not
 ** enough information about the compound query is known at that point.
 ** The KeyInfo for addrOpenTran[0] and [1] contains collating sequences
-** for the result set.  The KeyInfo for addrOpenTran[2] contains collating
+** for the result set.  The KeyInfo for addrOpenEphm[2] contains collating
 ** sequences for the ORDER BY clause.
 */
 struct Select {
   ExprList *pEList;      /* The fields of the result */
   u8 op;                 /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
-  char affinity;         /* MakeRecord with this affinity for SRT_Set */
   u16 selFlags;          /* Various SF_* values */
   int iLimit, iOffset;   /* Memory registers holding LIMIT & OFFSET counters */
   int addrOpenEphm[3];   /* OP_OpenEphem opcodes related to this select */
@@ -11051,14 +11164,15 @@ struct Select {
 ** Allowed values for Select.selFlags.  The "SF" prefix stands for
 ** "Select Flag".
 */
-#define SF_Distinct        0x01  /* Output should be DISTINCT */
-#define SF_Resolved        0x02  /* Identifiers have been resolved */
-#define SF_Aggregate       0x04  /* Contains aggregate functions */
-#define SF_UsesEphemeral   0x08  /* Uses the OpenEphemeral opcode */
-#define SF_Expanded        0x10  /* sqlite3SelectExpand() called on this */
-#define SF_HasTypeInfo     0x20  /* FROM subqueries have Table metadata */
-#define SF_UseSorter       0x40  /* Sort using a sorter */
-#define SF_Values          0x80  /* Synthesized from VALUES clause */
+#define SF_Distinct        0x0001  /* Output should be DISTINCT */
+#define SF_Resolved        0x0002  /* Identifiers have been resolved */
+#define SF_Aggregate       0x0004  /* Contains aggregate functions */
+#define SF_UsesEphemeral   0x0008  /* Uses the OpenEphemeral opcode */
+#define SF_Expanded        0x0010  /* sqlite3SelectExpand() called on this */
+#define SF_HasTypeInfo     0x0020  /* FROM subqueries have Table metadata */
+#define SF_UseSorter       0x0040  /* Sort using a sorter */
+#define SF_Values          0x0080  /* Synthesized from VALUES clause */
+#define SF_Materialize     0x0100  /* Force materialization of views */
 
 
 /*
@@ -11081,16 +11195,15 @@ struct Select {
 #define SRT_Coroutine   10  /* Generate a single row of result */
 
 /*
-** A structure used to customize the behavior of sqlite3Select(). See
-** comments above sqlite3Select() for details.
+** An instance of this object describes where to put of the results of
+** a SELECT statement.
 */
-typedef struct SelectDest SelectDest;
 struct SelectDest {
-  u8 eDest;         /* How to dispose of the results */
-  u8 affinity;      /* Affinity used when eDest==SRT_Set */
-  int iParm;        /* A parameter used by the eDest disposal method */
-  int iMem;         /* Base register where results are written */
-  int nMem;         /* Number of registers allocated */
+  u8 eDest;         /* How to dispose of the results.  On of SRT_* above. */
+  char affSdst;     /* Affinity used when eDest==SRT_Set */
+  int iSDParm;      /* A parameter used by the eDest disposal method */
+  int iSdst;        /* Base register where results are written */
+  int nSdst;        /* Number of registers allocated */
 };
 
 /*
@@ -11286,6 +11399,9 @@ struct AuthContext {
 #define OPFLAG_CLEARCACHE    0x20    /* Clear pseudo-table cache in OP_Column */
 #define OPFLAG_LENGTHARG     0x40    /* OP_Column only used for length() */
 #define OPFLAG_TYPEOFARG     0x80    /* OP_Column only used for typeof() */
+#define OPFLAG_BULKCSR       0x01    /* OP_Open** used to open bulk cursor */
+#define OPFLAG_P2ISREG       0x02    /* P2 to OP_Open** is a register number */
+#define OPFLAG_PERMUTE       0x01    /* OP_Compare: use the permutation */
 
 /*
  * Each trigger present in the database schema is stored as an instance of
@@ -11385,6 +11501,7 @@ struct TriggerStep {
 typedef struct DbFixer DbFixer;
 struct DbFixer {
   Parse *pParse;      /* The parsing context.  Error messages written here */
+  Schema *pSchema;    /* Fix items to this schema */
   const char *zDb;    /* Make sure all objects are contained in this database */
   const char *zType;  /* Type of the container - used for error messages */
   const Token *pName; /* Name of the container - used for error messages */
@@ -11427,6 +11544,7 @@ struct Sqlite3Config {
   int bCoreMutex;                   /* True to enable core mutexing */
   int bFullMutex;                   /* True to enable full mutexing */
   int bOpenUri;                     /* True to interpret filenames as URIs */
+  int bUseCis;                      /* Use covering indices for full-scans */
   int mxStrlen;                     /* Maximum string length */
   int szLookaside;                  /* Default lookaside buffer size */
   int nLookaside;                   /* Default lookaside buffer count */
@@ -11456,6 +11574,10 @@ struct Sqlite3Config {
   void (*xLog)(void*,int,const char*); /* Function for logging */
   void *pLogArg;                       /* First argument to xLog() */
   int bLocaltimeFault;              /* True to fail localtime() calls */
+#ifdef SQLITE_ENABLE_SQLLOG
+  void(*xSqllog)(void*,sqlite3*,const char*, int);
+  void *pSqllogArg;
+#endif
 };
 
 /*
@@ -11465,10 +11587,12 @@ struct Walker {
   int (*xExprCallback)(Walker*, Expr*);     /* Callback for expressions */
   int (*xSelectCallback)(Walker*,Select*);  /* Callback for SELECTs */
   Parse *pParse;                            /* Parser context.  */
+  int walkerDepth;                          /* Number of subqueries */
   union {                                   /* Extra data for callback */
     NameContext *pNC;                          /* Naming context */
     int i;                                     /* Integer value */
     SrcList *pSrcList;                         /* FROM clause */
+    struct SrcCount *pSrcCount;                /* Counting column references */
   } u;
 };
 
@@ -11741,6 +11865,7 @@ SQLITE_PRIVATE   void sqlite3AutoincrementEnd(Parse *pParse);
 # define sqlite3AutoincrementBegin(X)
 # define sqlite3AutoincrementEnd(X)
 #endif
+SQLITE_PRIVATE int sqlite3CodeCoroutine(Parse*, Select*, SelectDest*);
 SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int);
 SQLITE_PRIVATE void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*);
 SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*);
@@ -11770,12 +11895,11 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse *, SrcList *, Expr *, ExprList *, E
 #endif
 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);
+SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
 SQLITE_PRIVATE void sqlite3WhereEnd(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);
-SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, int, int, int);
 SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse*, int, int, int);
 SQLITE_PRIVATE void sqlite3ExprCachePush(Parse*);
 SQLITE_PRIVATE void sqlite3ExprCachePop(Parse*, int);
@@ -11792,6 +11916,7 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
 SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
 SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3*,const char*, const char*);
 SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,int isView,const char*, const char*);
+SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,int isView,struct SrcList_item *);
 SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
 SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
 SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
@@ -11802,6 +11927,7 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*);
 SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*);
 SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
 SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
+SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
 SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*);
 SQLITE_PRIVATE void sqlite3PrngSaveState(void);
 SQLITE_PRIVATE void sqlite3PrngRestoreState(void);
@@ -11814,6 +11940,7 @@ SQLITE_PRIVATE void sqlite3CommitTransaction(Parse*);
 SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse*);
 SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*);
 SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *);
+SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
 SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*);
 SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*);
 SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*);
@@ -11913,7 +12040,7 @@ SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*);
 SQLITE_PRIVATE int sqlite3Atoi(const char*);
 SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar);
 SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte);
-SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8*, const u8**);
+SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**);
 
 /*
 ** Routines to read and write variable-length integers.  These used to
@@ -11966,8 +12093,9 @@ SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse);
 SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
 SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
 SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
-SQLITE_PRIVATE Expr *sqlite3ExprSetColl(Expr*, CollSeq*);
-SQLITE_PRIVATE Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr*, Token*);
+SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, Token*);
+SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
+SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*);
 SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *);
 SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *);
 SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int);
@@ -12020,7 +12148,7 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const
 SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
 SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
 SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
-SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(sqlite3*, u8, CollSeq *, const char*);
+SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
 SQLITE_PRIVATE char sqlite3AffinityType(const char*);
 SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*);
 SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*);
@@ -12124,8 +12252,10 @@ SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
 SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
 SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3*);
 SQLITE_PRIVATE const char *sqlite3JournalModename(int);
-SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3*, int, int, int*, int*);
-SQLITE_PRIVATE int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
+#ifndef SQLITE_OMIT_WAL
+SQLITE_PRIVATE   int sqlite3Checkpoint(sqlite3*, int, int, int*, int*);
+SQLITE_PRIVATE   int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
+#endif
 
 /* Declarations for functions in fkey.c. All of these are replaced by
 ** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign
@@ -12183,8 +12313,10 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, int*);
 SQLITE_PRIVATE   int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
 SQLITE_PRIVATE   int sqlite3JournalSize(sqlite3_vfs *);
 SQLITE_PRIVATE   int sqlite3JournalCreate(sqlite3_file *);
+SQLITE_PRIVATE   int sqlite3JournalExists(sqlite3_file *p);
 #else
   #define sqlite3JournalSize(pVfs) ((pVfs)->szOsFile)
+  #define sqlite3JournalExists(p) 1
 #endif
 
 SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *);
@@ -12413,6 +12545,10 @@ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
 # define  SQLITE_USE_URI 0
 #endif
 
+#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
+# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1
+#endif
+
 /*
 ** The following singleton contains the global configuration for
 ** the SQLite library.
@@ -12422,6 +12558,7 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
    1,                         /* bCoreMutex */
    SQLITE_THREADSAFE==1,      /* bFullMutex */
    SQLITE_USE_URI,            /* bOpenUri */
+   SQLITE_ALLOW_COVERING_INDEX_SCAN,   /* bUseCis */
    0x7ffffffe,                /* mxStrlen */
    128,                       /* szLookaside */
    500,                       /* nLookaside */
@@ -12450,6 +12587,10 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
    0,                         /* xLog */
    0,                         /* pLogArg */
    0,                         /* bLocaltimeFault */
+#ifdef SQLITE_ENABLE_SQLLOG
+   0,                         /* xSqllog */
+   0                          /* pSqllogArg */
+#endif
 };
 
 
@@ -12840,6 +12981,9 @@ static const char * const azCompileOpt[] = {
 #ifdef SQLITE_PROXY_DEBUG
   "PROXY_DEBUG",
 #endif
+#ifdef SQLITE_RTREE_INT_ONLY
+  "RTREE_INT_ONLY",
+#endif
 #ifdef SQLITE_SECURE_DELETE
   "SECURE_DELETE",
 #endif
@@ -12987,6 +13131,7 @@ struct VdbeCursor {
   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 */
@@ -13111,7 +13256,9 @@ struct Mem {
 #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_TypeMask  0x00ff   /* Mask of type bits */
+#define MEM_Cleared   0x0100   /* NULL set by OP_Null, not from data */
+#define MEM_TypeMask  0x01ff   /* Mask of type bits */
+
 
 /* Whenever Mem contains a valid string or blob representation, one of
 ** the following flags must be set to determine the memory management
@@ -13197,6 +13344,11 @@ struct Explain {
   char zBase[100];   /* Initial space */
 };
 
+/* A bitfield type for use inside of structures.  Always follow with :N where
+** N is the number of bits.
+*/
+typedef unsigned bft;  /* Bit Field Type */
+
 /*
 ** An instance of the virtual machine.  This structure contains the complete
 ** state of the virtual machine.
@@ -13238,15 +13390,16 @@ struct Vdbe {
   int pc;                 /* The program counter */
   int rc;                 /* Value to return */
   u8 errorAction;         /* Recovery action to do in case of an error */
-  u8 explain;             /* True if EXPLAIN present on SQL command */
-  u8 changeCntOn;         /* True to update the change-counter */
-  u8 expired;             /* True if the VM needs to be recompiled */
-  u8 runOnlyOnce;         /* Automatically expire on reset */
   u8 minWriteFileFormat;  /* Minimum file format for writable database files */
-  u8 inVtabMethod;        /* See comments above */
-  u8 usesStmtJournal;     /* True if uses a statement journal */
-  u8 readOnly;            /* True for read-only statements */
-  u8 isPrepareV2;         /* True if prepared with prepare_v2() */
+  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 */
@@ -13355,11 +13508,11 @@ SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p);
 #else
 SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *);
 SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *);
-SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *, Mem *);
-SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, VdbeCursor *, int *);
-SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *, VdbeCursor *, int *);
-SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *, VdbeCursor *, Mem *);
-SQLITE_PRIVATE int sqlite3VdbeSorterCompare(VdbeCursor *, Mem *, int *);
+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 *);
 #endif
 
 #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
@@ -13592,7 +13745,8 @@ SQLITE_API int sqlite3_db_status(
 
       db->pnBytesFreed = &nByte;
       for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){
-        sqlite3VdbeDeleteObject(db, pVdbe);
+        sqlite3VdbeClearObject(db, pVdbe);
+        sqlite3DbFree(db, pVdbe);
       }
       db->pnBytesFreed = 0;
 
@@ -15506,14 +15660,14 @@ static int sqlite3MemInit(void *NotUsed){
   }else{
     /* only 1 core, use our own zone to contention over global locks, 
     ** e.g. we have our own dedicated locks */
-    bool success;              
+    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 ){    
+    if( !success ){
       /* somebody registered a zone first */
       malloc_destroy_zone(newzone);
     }
@@ -17719,7 +17873,7 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
 #endif /* !defined(SQLITE_MUTEX_OMIT) */
 
 /************** End of mutex_noop.c ******************************************/
-/************** Begin file mutex_os2.c ***************************************/
+/************** Begin file mutex_unix.c **************************************/
 /*
 ** 2007 August 28
 **
@@ -17731,49 +17885,85 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** This file contains the C functions that implement mutexes for OS/2
+** This file contains the C functions that implement mutexes for pthreads
 */
 
 /*
-** The code in this file is only used if SQLITE_MUTEX_OS2 is defined.
-** See the mutex.h file for details.
+** 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.
 */
-#ifdef SQLITE_MUTEX_OS2
+#ifdef SQLITE_MUTEX_PTHREADS
 
-/********************** OS/2 Mutex Implementation **********************
-**
-** This implementation of mutexes is built using the OS/2 API.
+#include <pthread.h>
+
+/*
+** 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.
 */
+#if defined(SQLITE_DEBUG) || defined(SQLITE_HOMEGROWN_RECURSIVE_MUTEX)
+# define SQLITE_MUTEX_NREF 1
+#else
+# define SQLITE_MUTEX_NREF 0
+#endif
 
 /*
-** The mutex object
 ** Each recursive mutex is an instance of the following structure.
 */
 struct sqlite3_mutex {
-  HMTX mutex;       /* Mutex controlling the lock */
-  int  id;          /* Mutex type */
-#ifdef SQLITE_DEBUG
- int   trace;       /* True to trace changes */
+  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
 };
-
-#ifdef SQLITE_DEBUG
-#define SQLITE3_MUTEX_INITIALIZER { 0, 0, 0 }
+#if SQLITE_MUTEX_NREF
+#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0, (pthread_t)0, 0 }
 #else
-#define SQLITE3_MUTEX_INITIALIZER { 0, 0 }
+#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }
+#endif
+
+/*
+** 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()));
+}
+static int pthreadMutexNotheld(sqlite3_mutex *p){
+  return p->nRef==0 || pthread_equal(p->owner, pthread_self())==0;
+}
 #endif
 
 /*
 ** Initialize and deinitialize the mutex subsystem.
 */
-static int os2MutexInit(void){ return SQLITE_OK; }
-static int os2MutexEnd(void){ return SQLITE_OK; }
+static int pthreadMutexInit(void){ return SQLITE_OK; }
+static int pthreadMutexEnd(void){ return SQLITE_OK; }
 
 /*
 ** 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
+** 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>
@@ -17784,7 +17974,7 @@ static int os2MutexEnd(void){ return SQLITE_OK; }
 ** <li>  SQLITE_MUTEX_STATIC_MEM2
 ** <li>  SQLITE_MUTEX_STATIC_PRNG
 ** <li>  SQLITE_MUTEX_STATIC_LRU
-** <li>  SQLITE_MUTEX_STATIC_LRU2
+** <li>  SQLITE_MUTEX_STATIC_PMEM
 ** </ul>
 **
 ** The first two constants cause sqlite3_mutex_alloc() to create
@@ -17807,67 +17997,59 @@ static int os2MutexEnd(void){ return SQLITE_OK; }
 **
 ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
 ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
-** returns a different mutex on every call.  But for the static
+** returns a different mutex on every call.  But for the static 
 ** mutex types, the same mutex is returned on every call that has
 ** the same type number.
 */
-static sqlite3_mutex *os2MutexAlloc(int iType){
-  sqlite3_mutex *p = NULL;
+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_FAST:
     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;
-        if( DosCreateMutexSem( 0, &p->mutex, 0, FALSE ) != NO_ERROR ){
-          sqlite3_free( p );
-          p = NULL;
-        }
+#endif
+        pthread_mutex_init(&p->mutex, 0);
       }
       break;
     }
     default: {
-      static volatile int isInit = 0;
-      static sqlite3_mutex staticMutexes[6] = {
-        SQLITE3_MUTEX_INITIALIZER,
-        SQLITE3_MUTEX_INITIALIZER,
-        SQLITE3_MUTEX_INITIALIZER,
-        SQLITE3_MUTEX_INITIALIZER,
-        SQLITE3_MUTEX_INITIALIZER,
-        SQLITE3_MUTEX_INITIALIZER,
-      };
-      if ( !isInit ){
-        APIRET rc;
-        PTIB ptib;
-        PPIB ppib;
-        HMTX mutex;
-        char name[32];
-        DosGetInfoBlocks( &ptib, &ppib );
-        sqlite3_snprintf( sizeof(name), name, "\\SEM32\\SQLITE%04x",
-                          ppib->pib_ulpid );
-        while( !isInit ){
-          mutex = 0;
-          rc = DosCreateMutexSem( name, &mutex, 0, FALSE);
-          if( rc == NO_ERROR ){
-            unsigned int i;
-            if( !isInit ){
-              for( i = 0; i < sizeof(staticMutexes)/sizeof(staticMutexes[0]); i++ ){
-                DosCreateMutexSem( 0, &staticMutexes[i].mutex, 0, FALSE );
-              }
-              isInit = 1;
-            }
-            DosCloseMutexSem( mutex );
-          }else if( rc == ERROR_DUPLICATE_NAME ){
-            DosSleep( 1 );
-          }else{
-            return p;
-          }
-        }
-      }
       assert( iType-2 >= 0 );
-      assert( iType-2 < sizeof(staticMutexes)/sizeof(staticMutexes[0]) );
+      assert( iType-2 < ArraySize(staticMutexes) );
       p = &staticMutexes[iType-2];
+#if SQLITE_MUTEX_NREF
       p->id = iType;
+#endif
       break;
     }
   }
@@ -17876,57 +18058,16 @@ static sqlite3_mutex *os2MutexAlloc(int iType){
 
 
 /*
-** This routine deallocates a previously allocated mutex.
-** SQLite is careful to deallocate every mutex that it allocates.
+** This routine deallocates a previously
+** allocated mutex.  SQLite is careful to deallocate every
+** mutex that it allocates.
 */
-static void os2MutexFree(sqlite3_mutex *p){
-#ifdef SQLITE_DEBUG
-  TID tid;
-  PID pid;
-  ULONG ulCount;
-  DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
-  assert( ulCount==0 );
+static void pthreadMutexFree(sqlite3_mutex *p){
+  assert( p->nRef==0 );
   assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
-#endif
-  DosCloseMutexSem( p->mutex );
-  sqlite3_free( p );
-}
-
-#ifdef SQLITE_DEBUG
-/*
-** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
-** intended for use inside assert() statements.
-*/
-static int os2MutexHeld(sqlite3_mutex *p){
-  TID tid;
-  PID pid;
-  ULONG ulCount;
-  PTIB ptib;
-  DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
-  if( ulCount==0 || ( ulCount>1 && p->id!=SQLITE_MUTEX_RECURSIVE ) )
-    return 0;
-  DosGetInfoBlocks(&ptib, NULL);
-  return tid==ptib->tib_ptib2->tib2_ultid;
-}
-static int os2MutexNotheld(sqlite3_mutex *p){
-  TID tid;
-  PID pid;
-  ULONG ulCount;
-  PTIB ptib;
-  DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
-  if( ulCount==0 )
-    return 1;
-  DosGetInfoBlocks(&ptib, NULL);
-  return tid!=ptib->tib_ptib2->tib2_ultid;
-}
-static void os2MutexTrace(sqlite3_mutex *p, char *pAction){
-  TID   tid;
-  PID   pid;
-  ULONG ulCount;
-  DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
-  printf("%s mutex %p (%d) with nRef=%ld\n", pAction, (void*)p, p->trace, ulCount);
+  pthread_mutex_destroy(&p->mutex);
+  sqlite3_free(p);
 }
-#endif
 
 /*
 ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
@@ -17939,22 +18080,96 @@ static void os2MutexTrace(sqlite3_mutex *p, char *pAction){
 ** can enter.  If the same thread tries to enter any other kind of mutex
 ** more than once, the behavior is undefined.
 */
-static void os2MutexEnter(sqlite3_mutex *p){
-  assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) );
-  DosRequestMutexSem(p->mutex, SEM_INDEFINITE_WAIT);
+static void pthreadMutexEnter(sqlite3_mutex *p){
+  assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) );
+
+#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.
+  */
+  {
+    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.
+  */
+  pthread_mutex_lock(&p->mutex);
+#if SQLITE_MUTEX_NREF
+  assert( p->nRef>0 || p->owner==0 );
+  p->owner = pthread_self();
+  p->nRef++;
+#endif
+#endif
+
 #ifdef SQLITE_DEBUG
-  if( p->trace ) os2MutexTrace(p, "enter");
+  if( p->trace ){
+    printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
+  }
 #endif
 }
-static int os2MutexTry(sqlite3_mutex *p){
-  int rc = SQLITE_BUSY;
-  assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) );
-  if( DosRequestMutexSem(p->mutex, SEM_IMMEDIATE_RETURN) == NO_ERROR ) {
+static int pthreadMutexTry(sqlite3_mutex *p){
+  int rc;
+  assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) );
+
+#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.
+  */
+  {
+    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.
+  */
+  if( pthread_mutex_trylock(&p->mutex)==0 ){
+#if SQLITE_MUTEX_NREF
+    p->owner = pthread_self();
+    p->nRef++;
+#endif
     rc = SQLITE_OK;
-#ifdef SQLITE_DEBUG
-    if( p->trace ) os2MutexTrace(p, "try");
+  }else{
+    rc = SQLITE_BUSY;
+  }
 #endif
+
+#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;
 }
 
@@ -17964,26 +18179,41 @@ static int os2MutexTry(sqlite3_mutex *p){
 ** is undefined if the mutex is not currently entered or
 ** is not currently allocated.  SQLite will never do either.
 */
-static void os2MutexLeave(sqlite3_mutex *p){
-  assert( os2MutexHeld(p) );
-  DosReleaseMutexSem(p->mutex);
+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);
+  }
+#else
+  pthread_mutex_unlock(&p->mutex);
+#endif
+
 #ifdef SQLITE_DEBUG
-  if( p->trace ) os2MutexTrace(p, "leave");
+  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 = {
-    os2MutexInit,
-    os2MutexEnd,
-    os2MutexAlloc,
-    os2MutexFree,
-    os2MutexEnter,
-    os2MutexTry,
-    os2MutexLeave,
+    pthreadMutexInit,
+    pthreadMutexEnd,
+    pthreadMutexAlloc,
+    pthreadMutexFree,
+    pthreadMutexEnter,
+    pthreadMutexTry,
+    pthreadMutexLeave,
 #ifdef SQLITE_DEBUG
-    os2MutexHeld,
-    os2MutexNotheld
+    pthreadMutexHeld,
+    pthreadMutexNotheld
 #else
     0,
     0
@@ -17992,12 +18222,13 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
 
   return &sMutex;
 }
-#endif /* SQLITE_MUTEX_OS2 */
 
-/************** End of mutex_os2.c *******************************************/
-/************** Begin file mutex_unix.c **************************************/
+#endif /* SQLITE_MUTEX_PTHREADS */
+
+/************** End of mutex_unix.c ******************************************/
+/************** Begin file mutex_w32.c ***************************************/
 /*
-** 2007 August 28
+** 2007 August 14
 **
 ** The author disclaims copyright to this source code.  In place of
 ** a legal notice, here is a blessing:
@@ -18007,495 +18238,142 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** 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.
+** This file contains the C functions that implement mutexes for win32
 */
-#ifdef SQLITE_MUTEX_PTHREADS
-
-#include <pthread.h>
 
 /*
-** 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 code in this file is only used if we are compiling multithreaded
+** on a win32 system.
 */
-#if defined(SQLITE_DEBUG) || defined(SQLITE_HOMEGROWN_RECURSIVE_MUTEX)
-# define SQLITE_MUTEX_NREF 1
-#else
-# define SQLITE_MUTEX_NREF 0
-#endif
+#ifdef SQLITE_MUTEX_W32
 
 /*
 ** 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
+  CRITICAL_SECTION mutex;    /* Mutex controlling the lock */
   int id;                    /* Mutex type */
-  volatile int nRef;         /* Number of entrances */
-  volatile pthread_t owner;  /* Thread that is within this mutex */
+#ifdef SQLITE_DEBUG
+  volatile int nRef;         /* Number of enterances */
+  volatile DWORD owner;      /* Thread holding 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 }
+#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 { PTHREAD_MUTEX_INITIALIZER }
+#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 }
 #endif
 
 /*
-** 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.
+** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
+** or WinCE.  Return false (zero) for Win95, Win98, or WinME.
 **
-** 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.
+** 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.
 */
-#if !defined(NDEBUG) || defined(SQLITE_DEBUG)
-static int pthreadMutexHeld(sqlite3_mutex *p){
-  return (p->nRef!=0 && pthread_equal(p->owner, pthread_self()));
+#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;
+  }
+#endif /* SQLITE_OS_WINCE */
+#endif
+
+#ifdef SQLITE_DEBUG
+/*
+** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
+** intended for use only inside assert() statements.
+*/
+static int winMutexHeld(sqlite3_mutex *p){
+  return p->nRef!=0 && p->owner==GetCurrentThreadId();
 }
-static int pthreadMutexNotheld(sqlite3_mutex *p){
-  return p->nRef==0 || pthread_equal(p->owner, pthread_self())==0;
+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
 
+
 /*
 ** Initialize and deinitialize the mutex subsystem.
 */
-static int pthreadMutexInit(void){ return SQLITE_OK; }
-static int pthreadMutexEnd(void){ return SQLITE_OK; }
-
-/*
-** 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.
-*/
-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;
-}
-
-
-/*
-** 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);
-}
-
-/*
-** 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.
-*/
-static void pthreadMutexEnter(sqlite3_mutex *p){
-  assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) );
-
-#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.
-  */
-  {
-    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.
-  */
-  pthread_mutex_lock(&p->mutex);
-#if SQLITE_MUTEX_NREF
-  assert( p->nRef>0 || p->owner==0 );
-  p->owner = pthread_self();
-  p->nRef++;
-#endif
-#endif
-
-#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) );
-
-#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.
-  */
-  {
-    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.
-  */
-  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
-
-#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.
-*/
-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);
-  }
-#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);
-  }
-#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.
-**
-*************************************************************************
-** This file contains the C functions that implement mutexes for win32
-*/
-
-/*
-** 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.
-**
-** 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.
-*/
-#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;
-  }
-#endif /* SQLITE_OS_WINCE */
-#endif
-
-#ifdef SQLITE_DEBUG
-/*
-** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
-** intended for use only inside assert() statements.
-*/
-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
-
-
-/*
-** 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.
-*/
-static long winMutex_lock = 0;
-
-SQLITE_API extern 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{
-    /* Someone else is in the process of initing the static mutexes */
-    while( !winMutex_isInit ){
-      sqlite3_win32_sleep(1);
-    }
-  }
-  return SQLITE_OK; 
-}
-
-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; 
-}
+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{
+    /* Someone else is in the process of initing the static mutexes */
+    while( !winMutex_isInit ){
+      sqlite3_win32_sleep(1);
+    }
+  }
+  return SQLITE_OK; 
+}
+
+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; 
+}
 
 /*
 ** The sqlite3_mutex_alloc() routine allocates a new
@@ -19602,7 +19480,8 @@ static const et_info fmtinfo[] = {
 static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
   int digit;
   LONGDOUBLE_TYPE d;
-  if( (*cnt)++ >= 16 ) return '0';
+  if( (*cnt)<=0 ) return '0';
+  (*cnt)--;
   digit = (int)*val;
   d = digit;
   digit += '0';
@@ -19906,9 +19785,12 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
           break;
         }
         if( realvalue>0.0 ){
-          while( realvalue>=1e32 && exp<=350 ){ realvalue *= 1e-32; exp+=32; }
-          while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; }
-          while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; }
+          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 ){
@@ -19941,7 +19823,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
             xtype = etFLOAT;
           }
         }else{
-          flag_rtz = 0;
+          flag_rtz = flag_altform2;
         }
         if( xtype==etEXP ){
           e2 = 0;
@@ -19956,7 +19838,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
           }
         }
         zOut = bufpt;
-        nsd = 0;
+        nsd = 16 + flag_altform2*10;
         flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
         /* The sign in front of the number */
         if( prefix ){
@@ -20760,25 +20642,23 @@ static const unsigned char sqlite3Utf8Trans1[] = {
         || (c&0xFFFFFFFE)==0xFFFE ){  c = 0xFFFD; }        \
   }
 SQLITE_PRIVATE u32 sqlite3Utf8Read(
-  const unsigned char *zIn,       /* First byte of UTF-8 character */
-  const unsigned char **pzNext    /* Write first byte past UTF-8 char here */
+  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 = *(zIn++);
+  c = *((*pz)++);
   if( c>=0xc0 ){
     c = sqlite3Utf8Trans1[c-0xc0];
-    while( (*zIn & 0xc0)==0x80 ){
-      c = (c<<6) + (0x3f & *(zIn++));
+    while( (*(*pz) & 0xc0)==0x80 ){
+      c = (c<<6) + (0x3f & *((*pz)++));
     }
     if( c<0x80
         || (c&0xFFFFF800)==0xD800
         || (c&0xFFFFFFFE)==0xFFFE ){  c = 0xFFFD; }
   }
-  *pzNext = zIn;
   return c;
 }
 
@@ -20879,7 +20759,6 @@ SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
     if( desiredEnc==SQLITE_UTF16LE ){
       /* UTF-8 -> UTF-16 Little-endian */
       while( zIn<zTerm ){
-        /* c = sqlite3Utf8Read(zIn, zTerm, (const u8**)&zIn); */
         READ_UTF8(zIn, zTerm, c);
         WRITE_UTF16LE(z, c);
       }
@@ -20887,7 +20766,6 @@ SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
       assert( desiredEnc==SQLITE_UTF16BE );
       /* UTF-8 -> UTF-16 Big-endian */
       while( zIn<zTerm ){
-        /* c = sqlite3Utf8Read(zIn, zTerm, (const u8**)&zIn); */
         READ_UTF8(zIn, zTerm, c);
         WRITE_UTF16BE(z, c);
       }
@@ -21015,7 +20893,7 @@ SQLITE_PRIVATE int sqlite3Utf8To8(unsigned char *zIn){
   u32 c;
 
   while( zIn[0] && zOut<=zIn ){
-    c = sqlite3Utf8Read(zIn, (const u8**)&zIn);
+    c = sqlite3Utf8Read((const u8**)&zIn);
     if( c!=0xfffd ){
       WRITE_UTF8(zOut, c);
     }
@@ -21120,7 +20998,7 @@ SQLITE_PRIVATE void sqlite3UtfSelfTest(void){
     assert( n>0 && n<=4 );
     z[0] = 0;
     z = zBuf;
-    c = sqlite3Utf8Read(z, (const u8**)&z);
+    c = sqlite3Utf8Read((const u8**)&z);
     t = i;
     if( i>=0xD800 && i<=0xDFFF ) t = 0xFFFD;
     if( (i&0xFFFFFFFE)==0xFFFE ) t = 0xFFFD;
@@ -21529,7 +21407,7 @@ do_atof_calc:
     /* if exponent, scale significand as appropriate
     ** and store in result. */
     if( e ){
-      double scale = 1.0;
+      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; }
@@ -22458,7 +22336,11 @@ static int rehash(Hash *pH, unsigned int new_size){
 
   /* 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.
+  ** 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) );
@@ -22534,7 +22416,7 @@ static void removeElementGivenHash(
   }
   sqlite3_free( elem );
   pH->count--;
-  if( pH->count<=0 ){
+  if( pH->count==0 ){
     assert( pH->first==0 );
     assert( pH->count==0 );
     sqlite3HashClear(pH);
@@ -22784,2140 +22666,6 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
 #endif
 
 /************** End of opcodes.c *********************************************/
-/************** Begin file os_os2.c ******************************************/
-/*
-** 2006 Feb 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 code that is specific to OS/2.
-*/
-
-
-#if SQLITE_OS_OS2
-
-/*
-** A Note About Memory Allocation:
-**
-** This driver uses malloc()/free() directly rather than going through
-** the SQLite-wrappers sqlite3_malloc()/sqlite3_free().  Those wrappers
-** are designed for use on embedded systems where memory is scarce and
-** malloc failures happen frequently.  OS/2 does not typically run on
-** embedded systems, and when it does the developers normally have bigger
-** problems to worry about than running out of memory.  So there is not
-** a compelling need to use the wrappers.
-**
-** But there is a good reason to not use the wrappers.  If we use the
-** wrappers then we will get simulated malloc() failures within this
-** driver.  And that causes all kinds of problems for our tests.  We
-** could enhance SQLite to deal with simulated malloc failures within
-** the OS driver, but the code to deal with those failure would not
-** be exercised on Linux (which does not need to malloc() in the driver)
-** and so we would have difficulty writing coverage tests for that
-** code.  Better to leave the code out, we think.
-**
-** The point of this discussion is as follows:  When creating a new
-** OS layer for an embedded system, if you use this file as an example,
-** avoid the use of malloc()/free().  Those routines work ok on OS/2
-** desktops but not so well in embedded systems.
-*/
-
-/*
-** Macros used to determine whether or not to use threads.
-*/
-#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE
-# define SQLITE_OS2_THREADS 1
-#endif
-
-/*
-** Include code that is common to all os_*.c files
-*/
-/************** Include os_common.h in the middle of os_os2.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.
-*/
-#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
-
-/*
-** 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.
-**
-******************************************************************************
-**
-** 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.
-*/
-#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__))
-
-  __inline__ sqlite_uint64 sqlite3Hwtime(void){
-      unsigned long val;
-      __asm__ __volatile__ ("rdtsc" : "=A" (val));
-      return val;
-  }
-#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;
-  }
-
-#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
-
-/*
-** 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
-#define SimulateIOErrorBenign(X)
-#define SimulateIOError(A)
-#define SimulateDiskfullError(A)
-#endif
-
-/*
-** 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
-#define OpenCounter(X)
-#endif
-
-#endif /* !defined(_OS_COMMON_H_) */
-
-/************** End of os_common.h *******************************************/
-/************** Continuing where we left off in os_os2.c *********************/
-
-/* Forward references */
-typedef struct os2File os2File;         /* The file structure */
-typedef struct os2ShmNode os2ShmNode;   /* A shared descritive memory node */
-typedef struct os2ShmLink os2ShmLink;   /* A connection to shared-memory */
-
-/*
-** The os2File structure is subclass of sqlite3_file specific for the OS/2
-** protability layer.
-*/
-struct os2File {
-  const sqlite3_io_methods *pMethod;  /* Always the first entry */
-  HFILE h;                  /* Handle for accessing the file */
-  int flags;                /* Flags provided to os2Open() */
-  int locktype;             /* Type of lock currently held on this file */
-  int szChunk;              /* Chunk size configured by FCNTL_CHUNK_SIZE */
-  char *zFullPathCp;        /* Full path name of this file */
-  os2ShmLink *pShmLink;     /* Instance of shared memory on this file */
-};
-
-#define LOCK_TIMEOUT 10L /* the default locking timeout */
-
-/*
-** Missing from some versions of the OS/2 toolkit -
-** used to allocate from high memory if possible
-*/
-#ifndef OBJ_ANY
-# define OBJ_ANY 0x00000400
-#endif
-
-/*****************************************************************************
-** The next group of routines implement the I/O methods specified
-** by the sqlite3_io_methods object.
-******************************************************************************/
-
-/*
-** Close a file.
-*/
-static int os2Close( sqlite3_file *id ){
-  APIRET rc;
-  os2File *pFile = (os2File*)id;
-
-  assert( id!=0 );
-  OSTRACE(( "CLOSE %d (%s)\n", pFile->h, pFile->zFullPathCp ));
-
-  rc = DosClose( pFile->h );
-
-  if( pFile->flags & SQLITE_OPEN_DELETEONCLOSE )
-    DosForceDelete( (PSZ)pFile->zFullPathCp );
-
-  free( pFile->zFullPathCp );
-  pFile->zFullPathCp = NULL;
-  pFile->locktype = NO_LOCK;
-  pFile->h = (HFILE)-1;
-  pFile->flags = 0;
-
-  OpenCounter( -1 );
-  return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
-}
-
-/*
-** 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 os2Read(
-  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 */
-){
-  ULONG fileLocation = 0L;
-  ULONG got;
-  os2File *pFile = (os2File*)id;
-  assert( id!=0 );
-  SimulateIOError( return SQLITE_IOERR_READ );
-  OSTRACE(( "READ %d lock=%d\n", pFile->h, pFile->locktype ));
-  if( DosSetFilePtr(pFile->h, offset, FILE_BEGIN, &fileLocation) != NO_ERROR ){
-    return SQLITE_IOERR;
-  }
-  if( DosRead( pFile->h, pBuf, amt, &got ) != NO_ERROR ){
-    return SQLITE_IOERR_READ;
-  }
-  if( got == (ULONG)amt )
-    return SQLITE_OK;
-  else {
-    /* Unread portions of the input buffer must be zero-filled */
-    memset(&((char*)pBuf)[got], 0, amt-got);
-    return SQLITE_IOERR_SHORT_READ;
-  }
-}
-
-/*
-** Write data from a buffer into a file.  Return SQLITE_OK on success
-** or some other error code on failure.
-*/
-static int os2Write(
-  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 */
-){
-  ULONG fileLocation = 0L;
-  APIRET rc = NO_ERROR;
-  ULONG wrote;
-  os2File *pFile = (os2File*)id;
-  assert( id!=0 );
-  SimulateIOError( return SQLITE_IOERR_WRITE );
-  SimulateDiskfullError( return SQLITE_FULL );
-  OSTRACE(( "WRITE %d lock=%d\n", pFile->h, pFile->locktype ));
-  if( DosSetFilePtr(pFile->h, offset, FILE_BEGIN, &fileLocation) != NO_ERROR ){
-    return SQLITE_IOERR;
-  }
-  assert( amt>0 );
-  while( amt > 0 &&
-         ( rc = DosWrite( pFile->h, (PVOID)pBuf, amt, &wrote ) ) == NO_ERROR &&
-         wrote > 0
-  ){
-    amt -= wrote;
-    pBuf = &((char*)pBuf)[wrote];
-  }
-
-  return ( rc != NO_ERROR || amt > (int)wrote ) ? SQLITE_FULL : SQLITE_OK;
-}
-
-/*
-** Truncate an open file to a specified size
-*/
-static int os2Truncate( sqlite3_file *id, i64 nByte ){
-  APIRET rc;
-  os2File *pFile = (os2File*)id;
-  assert( id!=0 );
-  OSTRACE(( "TRUNCATE %d %lld\n", pFile->h, nByte ));
-  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).
-  */
-  if( pFile->szChunk ){
-    nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
-  }
-  
-  rc = DosSetFileSize( pFile->h, nByte );
-  return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR_TRUNCATE;
-}
-
-#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.
-*/
-static int os2Sync( sqlite3_file *id, int flags ){
-  os2File *pFile = (os2File*)id;
-  OSTRACE(( "SYNC %d lock=%d\n", pFile->h, pFile->locktype ));
-#ifdef SQLITE_TEST
-  if( flags & SQLITE_SYNC_FULL){
-    sqlite3_fullsync_count++;
-  }
-  sqlite3_sync_count++;
-#endif
-  /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
-  ** no-op
-  */
-#ifdef SQLITE_NO_SYNC
-  UNUSED_PARAMETER(pFile);
-  return SQLITE_OK;
-#else
-  return DosResetBuffer( pFile->h ) == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
-#endif
-}
-
-/*
-** Determine the current size of a file in bytes
-*/
-static int os2FileSize( sqlite3_file *id, sqlite3_int64 *pSize ){
-  APIRET rc = NO_ERROR;
-  FILESTATUS3 fsts3FileInfo;
-  memset(&fsts3FileInfo, 0, sizeof(fsts3FileInfo));
-  assert( id!=0 );
-  SimulateIOError( return SQLITE_IOERR_FSTAT );
-  rc = DosQueryFileInfo( ((os2File*)id)->h, FIL_STANDARD, &fsts3FileInfo, sizeof(FILESTATUS3) );
-  if( rc == NO_ERROR ){
-    *pSize = fsts3FileInfo.cbFile;
-    return SQLITE_OK;
-  }else{
-    return SQLITE_IOERR_FSTAT;
-  }
-}
-
-/*
-** Acquire a reader lock.
-*/
-static int getReadLock( os2File *pFile ){
-  FILELOCK  LockArea,
-            UnlockArea;
-  APIRET res;
-  memset(&LockArea, 0, sizeof(LockArea));
-  memset(&UnlockArea, 0, sizeof(UnlockArea));
-  LockArea.lOffset = SHARED_FIRST;
-  LockArea.lRange = SHARED_SIZE;
-  UnlockArea.lOffset = 0L;
-  UnlockArea.lRange = 0L;
-  res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 1L );
-  OSTRACE(( "GETREADLOCK %d res=%d\n", pFile->h, res ));
-  return res;
-}
-
-/*
-** Undo a readlock
-*/
-static int unlockReadLock( os2File *id ){
-  FILELOCK  LockArea,
-            UnlockArea;
-  APIRET res;
-  memset(&LockArea, 0, sizeof(LockArea));
-  memset(&UnlockArea, 0, sizeof(UnlockArea));
-  LockArea.lOffset = 0L;
-  LockArea.lRange = 0L;
-  UnlockArea.lOffset = SHARED_FIRST;
-  UnlockArea.lRange = SHARED_SIZE;
-  res = DosSetFileLocks( id->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 1L );
-  OSTRACE(( "UNLOCK-READLOCK file handle=%d res=%d?\n", id->h, res ));
-  return res;
-}
-
-/*
-** 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 os2Unlock() 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 os2Lock( sqlite3_file *id, int locktype ){
-  int rc = SQLITE_OK;       /* Return code from subroutines */
-  APIRET res = NO_ERROR;    /* Result of an OS/2 lock call */
-  int newLocktype;       /* Set pFile->locktype to this value before exiting */
-  int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
-  FILELOCK  LockArea,
-            UnlockArea;
-  os2File *pFile = (os2File*)id;
-  memset(&LockArea, 0, sizeof(LockArea));
-  memset(&UnlockArea, 0, sizeof(UnlockArea));
-  assert( pFile!=0 );
-  OSTRACE(( "LOCK %d %d was %d\n", pFile->h, locktype, pFile->locktype ));
-
-  /* If there is already a lock of this type or more restrictive on the
-  ** os2File, do nothing. Don't use the end_lock: exit path, as
-  ** sqlite3_mutex_enter() hasn't been called yet.
-  */
-  if( pFile->locktype>=locktype ){
-    OSTRACE(( "LOCK %d %d ok (already held)\n", pFile->h, locktype ));
-    return SQLITE_OK;
-  }
-
-  /* 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 );
-
-  /* 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)
-  ){
-    LockArea.lOffset = PENDING_BYTE;
-    LockArea.lRange = 1L;
-    UnlockArea.lOffset = 0L;
-    UnlockArea.lRange = 0L;
-
-    /* wait longer than LOCK_TIMEOUT here not to have to try multiple times */
-    res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 100L, 0L );
-    if( res == NO_ERROR ){
-      gotPendingLock = 1;
-      OSTRACE(( "LOCK %d pending lock boolean set.  res=%d\n", pFile->h, res ));
-    }
-  }
-
-  /* Acquire a shared lock
-  */
-  if( locktype==SHARED_LOCK && res == NO_ERROR ){
-    assert( pFile->locktype==NO_LOCK );
-    res = getReadLock(pFile);
-    if( res == NO_ERROR ){
-      newLocktype = SHARED_LOCK;
-    }
-    OSTRACE(( "LOCK %d acquire shared lock. res=%d\n", pFile->h, res ));
-  }
-
-  /* Acquire a RESERVED lock
-  */
-  if( locktype==RESERVED_LOCK && res == NO_ERROR ){
-    assert( pFile->locktype==SHARED_LOCK );
-    LockArea.lOffset = RESERVED_BYTE;
-    LockArea.lRange = 1L;
-    UnlockArea.lOffset = 0L;
-    UnlockArea.lRange = 0L;
-    res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
-    if( res == NO_ERROR ){
-      newLocktype = RESERVED_LOCK;
-    }
-    OSTRACE(( "LOCK %d acquire reserved lock. res=%d\n", pFile->h, res ));
-  }
-
-  /* Acquire a PENDING lock
-  */
-  if( locktype==EXCLUSIVE_LOCK && res == NO_ERROR ){
-    newLocktype = PENDING_LOCK;
-    gotPendingLock = 0;
-    OSTRACE(( "LOCK %d acquire pending lock. pending lock boolean unset.\n",
-               pFile->h ));
-  }
-
-  /* Acquire an EXCLUSIVE lock
-  */
-  if( locktype==EXCLUSIVE_LOCK && res == NO_ERROR ){
-    assert( pFile->locktype>=SHARED_LOCK );
-    res = unlockReadLock(pFile);
-    OSTRACE(( "unreadlock = %d\n", res ));
-    LockArea.lOffset = SHARED_FIRST;
-    LockArea.lRange = SHARED_SIZE;
-    UnlockArea.lOffset = 0L;
-    UnlockArea.lRange = 0L;
-    res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
-    if( res == NO_ERROR ){
-      newLocktype = EXCLUSIVE_LOCK;
-    }else{
-      OSTRACE(( "OS/2 error-code = %d\n", res ));
-      getReadLock(pFile);
-    }
-    OSTRACE(( "LOCK %d acquire exclusive lock.  res=%d\n", pFile->h, res ));
-  }
-
-  /* If we are holding a PENDING lock that ought to be released, then
-  ** release it now.
-  */
-  if( gotPendingLock && locktype==SHARED_LOCK ){
-    int r;
-    LockArea.lOffset = 0L;
-    LockArea.lRange = 0L;
-    UnlockArea.lOffset = PENDING_BYTE;
-    UnlockArea.lRange = 1L;
-    r = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
-    OSTRACE(( "LOCK %d unlocking pending/is shared. r=%d\n", pFile->h, r ));
-  }
-
-  /* Update the state of the lock has held in the file descriptor then
-  ** return the appropriate result code.
-  */
-  if( res == NO_ERROR ){
-    rc = SQLITE_OK;
-  }else{
-    OSTRACE(( "LOCK FAILED %d trying for %d but got %d\n", pFile->h,
-              locktype, newLocktype ));
-    rc = SQLITE_BUSY;
-  }
-  pFile->locktype = newLocktype;
-  OSTRACE(( "LOCK %d now %d\n", pFile->h, pFile->locktype ));
-  return rc;
-}
-
-/*
-** 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 os2CheckReservedLock( sqlite3_file *id, int *pOut ){
-  int r = 0;
-  os2File *pFile = (os2File*)id;
-  assert( pFile!=0 );
-  if( pFile->locktype>=RESERVED_LOCK ){
-    r = 1;
-    OSTRACE(( "TEST WR-LOCK %d %d (local)\n", pFile->h, r ));
-  }else{
-    FILELOCK  LockArea,
-              UnlockArea;
-    APIRET rc = NO_ERROR;
-    memset(&LockArea, 0, sizeof(LockArea));
-    memset(&UnlockArea, 0, sizeof(UnlockArea));
-    LockArea.lOffset = RESERVED_BYTE;
-    LockArea.lRange = 1L;
-    UnlockArea.lOffset = 0L;
-    UnlockArea.lRange = 0L;
-    rc = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
-    OSTRACE(( "TEST WR-LOCK %d lock reserved byte rc=%d\n", pFile->h, rc ));
-    if( rc == NO_ERROR ){
-      APIRET rcu = NO_ERROR; /* return code for unlocking */
-      LockArea.lOffset = 0L;
-      LockArea.lRange = 0L;
-      UnlockArea.lOffset = RESERVED_BYTE;
-      UnlockArea.lRange = 1L;
-      rcu = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
-      OSTRACE(( "TEST WR-LOCK %d unlock reserved byte r=%d\n", pFile->h, rcu ));
-    }
-    r = !(rc == NO_ERROR);
-    OSTRACE(( "TEST WR-LOCK %d %d (remote)\n", pFile->h, r ));
-  }
-  *pOut = r;
-  return SQLITE_OK;
-}
-
-/*
-** Lower the locking level on file descriptor id to locktype.  locktype
-** must be either NO_LOCK or SHARED_LOCK.
-**
-** If the locking level of the file descriptor is already at or below
-** the requested locking level, this routine is a no-op.
-**
-** It is not possible for this routine to fail if the second argument
-** is NO_LOCK.  If the second argument is SHARED_LOCK then this routine
-** might return SQLITE_IOERR;
-*/
-static int os2Unlock( sqlite3_file *id, int locktype ){
-  int type;
-  os2File *pFile = (os2File*)id;
-  APIRET rc = SQLITE_OK;
-  APIRET res = NO_ERROR;
-  FILELOCK  LockArea,
-            UnlockArea;
-  memset(&LockArea, 0, sizeof(LockArea));
-  memset(&UnlockArea, 0, sizeof(UnlockArea));
-  assert( pFile!=0 );
-  assert( locktype<=SHARED_LOCK );
-  OSTRACE(( "UNLOCK %d to %d was %d\n", pFile->h, locktype, pFile->locktype ));
-  type = pFile->locktype;
-  if( type>=EXCLUSIVE_LOCK ){
-    LockArea.lOffset = 0L;
-    LockArea.lRange = 0L;
-    UnlockArea.lOffset = SHARED_FIRST;
-    UnlockArea.lRange = SHARED_SIZE;
-    res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
-    OSTRACE(( "UNLOCK %d exclusive lock res=%d\n", pFile->h, res ));
-    if( locktype==SHARED_LOCK && getReadLock(pFile) != NO_ERROR ){
-      /* This should never happen.  We should always be able to
-      ** reacquire the read lock */
-      OSTRACE(( "UNLOCK %d to %d getReadLock() failed\n", pFile->h, locktype ));
-      rc = SQLITE_IOERR_UNLOCK;
-    }
-  }
-  if( type>=RESERVED_LOCK ){
-    LockArea.lOffset = 0L;
-    LockArea.lRange = 0L;
-    UnlockArea.lOffset = RESERVED_BYTE;
-    UnlockArea.lRange = 1L;
-    res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
-    OSTRACE(( "UNLOCK %d reserved res=%d\n", pFile->h, res ));
-  }
-  if( locktype==NO_LOCK && type>=SHARED_LOCK ){
-    res = unlockReadLock(pFile);
-    OSTRACE(( "UNLOCK %d is %d want %d res=%d\n",
-              pFile->h, type, locktype, res ));
-  }
-  if( type>=PENDING_LOCK ){
-    LockArea.lOffset = 0L;
-    LockArea.lRange = 0L;
-    UnlockArea.lOffset = PENDING_BYTE;
-    UnlockArea.lRange = 1L;
-    res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
-    OSTRACE(( "UNLOCK %d pending res=%d\n", pFile->h, res ));
-  }
-  pFile->locktype = locktype;
-  OSTRACE(( "UNLOCK %d now %d\n", pFile->h, pFile->locktype ));
-  return rc;
-}
-
-/*
-** Control and query of the open file handle.
-*/
-static int os2FileControl(sqlite3_file *id, int op, void *pArg){
-  switch( op ){
-    case SQLITE_FCNTL_LOCKSTATE: {
-      *(int*)pArg = ((os2File*)id)->locktype;
-      OSTRACE(( "FCNTL_LOCKSTATE %d lock=%d\n",
-                ((os2File*)id)->h, ((os2File*)id)->locktype ));
-      return SQLITE_OK;
-    }
-    case SQLITE_FCNTL_CHUNK_SIZE: {
-      ((os2File*)id)->szChunk = *(int*)pArg;
-      return SQLITE_OK;
-    }
-    case SQLITE_FCNTL_SIZE_HINT: {
-      sqlite3_int64 sz = *(sqlite3_int64*)pArg;
-      SimulateIOErrorBenign(1);
-      os2Truncate(id, sz);
-      SimulateIOErrorBenign(0);
-      return SQLITE_OK;
-    }
-    case SQLITE_FCNTL_SYNC_OMITTED: {
-      return SQLITE_OK;
-    }
-  }
-  return SQLITE_NOTFOUND;
-}
-
-/*
-** 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 os2SectorSize(sqlite3_file *id){
-  UNUSED_PARAMETER(id);
-  return SQLITE_DEFAULT_SECTOR_SIZE;
-}
-
-/*
-** Return a vector of device characteristics.
-*/
-static int os2DeviceCharacteristics(sqlite3_file *id){
-  UNUSED_PARAMETER(id);
-  return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN;
-}
-
-
-/*
-** Character set conversion objects used by conversion routines.
-*/
-static UconvObject ucUtf8 = NULL; /* convert between UTF-8 and UCS-2 */
-static UconvObject uclCp = NULL;  /* convert between local codepage and UCS-2 */
-
-/*
-** Helper function to initialize the conversion objects from and to UTF-8.
-*/
-static void initUconvObjects( void ){
-  if( UniCreateUconvObject( UTF_8, &ucUtf8 ) != ULS_SUCCESS )
-    ucUtf8 = NULL;
-  if ( UniCreateUconvObject( (UniChar *)L"@path=yes", &uclCp ) != ULS_SUCCESS )
-    uclCp = NULL;
-}
-
-/*
-** Helper function to free the conversion objects from and to UTF-8.
-*/
-static void freeUconvObjects( void ){
-  if ( ucUtf8 )
-    UniFreeUconvObject( ucUtf8 );
-  if ( uclCp )
-    UniFreeUconvObject( uclCp );
-  ucUtf8 = NULL;
-  uclCp = NULL;
-}
-
-/*
-** Helper function to convert UTF-8 filenames to local OS/2 codepage.
-** The two-step process: first convert the incoming UTF-8 string
-** into UCS-2 and then from UCS-2 to the current codepage.
-** The returned char pointer has to be freed.
-*/
-static char *convertUtf8PathToCp( const char *in ){
-  UniChar tempPath[CCHMAXPATH];
-  char *out = (char *)calloc( CCHMAXPATH, 1 );
-
-  if( !out )
-    return NULL;
-
-  if( !ucUtf8 || !uclCp )
-    initUconvObjects();
-
-  /* determine string for the conversion of UTF-8 which is CP1208 */
-  if( UniStrToUcs( ucUtf8, tempPath, (char *)in, CCHMAXPATH ) != ULS_SUCCESS )
-    return out; /* if conversion fails, return the empty string */
-
-  /* conversion for current codepage which can be used for paths */
-  UniStrFromUcs( uclCp, out, tempPath, CCHMAXPATH );
-
-  return out;
-}
-
-/*
-** Helper function to convert filenames from local codepage to UTF-8.
-** The two-step process: first convert the incoming codepage-specific
-** string into UCS-2 and then from UCS-2 to the codepage of UTF-8.
-** The returned char pointer has to be freed.
-**
-** This function is non-static to be able to use this in shell.c and
-** similar applications that take command line arguments.
-*/
-char *convertCpPathToUtf8( const char *in ){
-  UniChar tempPath[CCHMAXPATH];
-  char *out = (char *)calloc( CCHMAXPATH, 1 );
-
-  if( !out )
-    return NULL;
-
-  if( !ucUtf8 || !uclCp )
-    initUconvObjects();
-
-  /* conversion for current codepage which can be used for paths */
-  if( UniStrToUcs( uclCp, tempPath, (char *)in, CCHMAXPATH ) != ULS_SUCCESS )
-    return out; /* if conversion fails, return the empty string */
-
-  /* determine string for the conversion of UTF-8 which is CP1208 */
-  UniStrFromUcs( ucUtf8, out, tempPath, CCHMAXPATH );
-
-  return out;
-}
-
-
-#ifndef SQLITE_OMIT_WAL
-
-/*
-** Use main database file for interprocess locking. If un-defined
-** a separate file is created for this purpose. The file will be
-** used only to set file locks. There will be no data written to it.
-*/
-#define SQLITE_OS2_NO_WAL_LOCK_FILE     
-
-#if 0
-static void _ERR_TRACE( const char *fmt, ... ) {
-  va_list  ap;
-  va_start(ap, fmt);
-  vfprintf(stderr, fmt, ap);
-  fflush(stderr);
-}
-#define ERR_TRACE(rc, msg)        \
-        if( (rc) != SQLITE_OK ) _ERR_TRACE msg;
-#else
-#define ERR_TRACE(rc, msg)
-#endif
-
-/*
-** Helper functions to obtain and relinquish the global mutex. The
-** global mutex is used to protect os2ShmNodeList.
-**
-** Function os2ShmMutexHeld() is used to assert() that the global mutex 
-** is held when required. This function is only used as part of assert() 
-** statements. e.g.
-**
-**   os2ShmEnterMutex()
-**     assert( os2ShmMutexHeld() );
-**   os2ShmLeaveMutex()
-*/
-static void os2ShmEnterMutex(void){
-  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-}
-static void os2ShmLeaveMutex(void){
-  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-}
-#ifdef SQLITE_DEBUG
-static int os2ShmMutexHeld(void) {
-  return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
-}
-int GetCurrentProcessId(void) {
-  PPIB pib;
-  DosGetInfoBlocks(NULL, &pib);
-  return (int)pib->pib_ulpid;
-}
-#endif
-
-/*
-** Object used to represent a the shared memory area for a single log file.
-** When multiple threads all reference the same log-summary, each thread has
-** its own os2File object, but they all point to a single instance of this 
-** object.  In other words, each log-summary is opened only once per process.
-**
-** os2ShmMutexHeld() 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:
-** 
-**      szRegion
-**      hLockFile
-**      shmBaseName
-**
-** Either os2ShmNode.mutex must be held or os2ShmNode.nRef==0 and
-** os2ShmMutexHeld() is true when reading or writing any other field
-** in this structure.
-**
-*/
-struct os2ShmNode {
-  sqlite3_mutex *mutex;      /* Mutex to access this object */
-  os2ShmNode *pNext;         /* Next in list of all os2ShmNode objects */
-
-  int szRegion;              /* Size of shared-memory regions */
-
-  int nRegion;               /* Size of array apRegion */
-  void **apRegion;           /* Array of pointers to shared-memory regions */
-
-  int nRef;                  /* Number of os2ShmLink objects pointing to this */
-  os2ShmLink *pFirst;        /* First os2ShmLink object pointing to this */
-
-  HFILE hLockFile;           /* File used for inter-process memory locking */
-  char shmBaseName[1];       /* Name of the memory object !!! must last !!! */
-};
-
-
-/*
-** 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:
-**
-**    os2Shm.pShmNode
-**    os2Shm.id
-**
-** All other fields are read/write.  The os2Shm.pShmNode->mutex must be held
-** while accessing any read/write fields.
-*/
-struct os2ShmLink {
-  os2ShmNode *pShmNode;      /* The underlying os2ShmNode object */
-  os2ShmLink *pNext;         /* Next os2Shm with the same os2ShmNode */
-  u32 sharedMask;            /* Mask of shared locks held */
-  u32 exclMask;              /* Mask of exclusive locks held */
-#ifdef SQLITE_DEBUG
-  u8 id;                     /* Id of this connection with its os2ShmNode */
-#endif
-};
-
-
-/*
-** A global list of all os2ShmNode objects.
-**
-** The os2ShmMutexHeld() must be true while reading or writing this list.
-*/
-static os2ShmNode *os2ShmNodeList = NULL;
-
-/*
-** Constants used for locking
-*/
-#ifdef  SQLITE_OS2_NO_WAL_LOCK_FILE
-#define OS2_SHM_BASE   (PENDING_BYTE + 0x10000)         /* first lock byte */
-#else
-#define OS2_SHM_BASE   ((22+SQLITE_SHM_NLOCK)*4)        /* first lock byte */
-#endif
-
-#define OS2_SHM_DMS    (OS2_SHM_BASE+SQLITE_SHM_NLOCK)  /* deadman switch */
-
-/*
-** Apply advisory locks for all n bytes beginning at ofst.
-*/
-#define _SHM_UNLCK  1   /* no lock */
-#define _SHM_RDLCK  2   /* shared lock, no wait */
-#define _SHM_WRLCK  3   /* exlusive lock, no wait */
-#define _SHM_WRLCK_WAIT 4 /* exclusive lock, wait */
-static int os2ShmSystemLock(
-  os2ShmNode *pNode,    /* Apply locks to this open shared-memory segment */
-  int lockType,         /* _SHM_UNLCK, _SHM_RDLCK, _SHM_WRLCK or _SHM_WRLCK_WAIT */
-  int ofst,             /* Offset to first byte to be locked/unlocked */
-  int nByte             /* Number of bytes to lock or unlock */
-){
-  APIRET rc;
-  FILELOCK area;
-  ULONG mode, timeout;
-
-  /* Access to the os2ShmNode object is serialized by the caller */
-  assert( sqlite3_mutex_held(pNode->mutex) || pNode->nRef==0 );
-
-  mode = 1;     /* shared lock */
-  timeout = 0;  /* no wait */
-  area.lOffset = ofst;
-  area.lRange = nByte;
-
-  switch( lockType ) {
-    case _SHM_WRLCK_WAIT:
-      timeout = (ULONG)-1;      /* wait forever */
-    case _SHM_WRLCK:
-      mode = 0;                 /* exclusive lock */
-    case _SHM_RDLCK:
-      rc = DosSetFileLocks(pNode->hLockFile, 
-                           NULL, &area, timeout, mode);
-      break;
-    /* case _SHM_UNLCK: */
-    default:
-      rc = DosSetFileLocks(pNode->hLockFile, 
-                           &area, NULL, 0, 0);
-      break;
-  }
-                          
-  OSTRACE(("SHM-LOCK %d %s %s 0x%08lx\n", 
-           pNode->hLockFile,
-           rc==SQLITE_OK ? "ok" : "failed",
-           lockType==_SHM_UNLCK ? "Unlock" : "Lock",
-           rc));
-
-  ERR_TRACE(rc, ("os2ShmSystemLock: %d %s\n", rc, pNode->shmBaseName))
-
-  return ( rc == 0 ) ?  SQLITE_OK : SQLITE_BUSY;
-}
-
-/*
-** Find an os2ShmNode in global list or allocate a new one, if not found.
-**
-** This is not a VFS shared-memory method; it is a utility function called
-** by VFS shared-memory methods.
-*/
-static int os2OpenSharedMemory( os2File *fd, int szRegion ) {
-  os2ShmLink *pLink;
-  os2ShmNode *pNode;
-  int cbShmName, rc = SQLITE_OK;
-  char shmName[CCHMAXPATH + 30];
-#ifndef SQLITE_OS2_NO_WAL_LOCK_FILE
-  ULONG action;
-#endif
-  
-  /* We need some additional space at the end to append the region number */
-  cbShmName = sprintf(shmName, "\\SHAREMEM\\%s", fd->zFullPathCp );
-  if( cbShmName >= CCHMAXPATH-8 )
-    return SQLITE_IOERR_SHMOPEN; 
-
-  /* Replace colon in file name to form a valid shared memory name */
-  shmName[10+1] = '!';
-
-  /* Allocate link object (we free it later in case of failure) */
-  pLink = sqlite3_malloc( sizeof(*pLink) );
-  if( !pLink )
-    return SQLITE_NOMEM;
-
-  /* Access node list */
-  os2ShmEnterMutex();
-
-  /* Find node by it's shared memory base name */
-  for( pNode = os2ShmNodeList; 
-       pNode && stricmp(shmName, pNode->shmBaseName) != 0; 
-       pNode = pNode->pNext )   ;
-
-  /* Not found: allocate a new node */
-  if( !pNode ) {
-    pNode = sqlite3_malloc( sizeof(*pNode) + cbShmName );
-    if( pNode ) {
-      memset(pNode, 0, sizeof(*pNode) );
-      pNode->szRegion = szRegion;
-      pNode->hLockFile = (HFILE)-1;      
-      strcpy(pNode->shmBaseName, shmName);
-
-#ifdef SQLITE_OS2_NO_WAL_LOCK_FILE
-      if( DosDupHandle(fd->h, &pNode->hLockFile) != 0 ) {
-#else
-      sprintf(shmName, "%s-lck", fd->zFullPathCp);
-      if( DosOpen((PSZ)shmName, &pNode->hLockFile, &action, 0, FILE_NORMAL, 
-                  OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW,
-                  OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE | 
-                  OPEN_FLAGS_NOINHERIT | OPEN_FLAGS_FAIL_ON_ERROR,
-                  NULL) != 0 ) {
-#endif
-        sqlite3_free(pNode);  
-        rc = SQLITE_IOERR;
-      } else {
-        pNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
-        if( !pNode->mutex ) {
-          sqlite3_free(pNode);  
-          rc = SQLITE_NOMEM;
-        }
-      }   
-    } else {
-      rc = SQLITE_NOMEM;
-    }
-    
-    if( rc == SQLITE_OK ) {
-      pNode->pNext = os2ShmNodeList;
-      os2ShmNodeList = pNode;
-    } else {
-      pNode = NULL;
-    }
-  } else if( pNode->szRegion != szRegion ) {
-    rc = SQLITE_IOERR_SHMSIZE;
-    pNode = NULL;
-  }
-
-  if( pNode ) {
-    sqlite3_mutex_enter(pNode->mutex);
-
-    memset(pLink, 0, sizeof(*pLink));
-
-    pLink->pShmNode = pNode;
-    pLink->pNext = pNode->pFirst;
-    pNode->pFirst = pLink;
-    pNode->nRef++;
-
-    fd->pShmLink = pLink;
-
-    sqlite3_mutex_leave(pNode->mutex);
-    
-  } else {
-    /* Error occured. Free our link object. */
-    sqlite3_free(pLink);  
-  }
-
-  os2ShmLeaveMutex();
-
-  ERR_TRACE(rc, ("os2OpenSharedMemory: %d  %s\n", rc, fd->zFullPathCp))  
-  
-  return rc;
-}
-
-/*
-** Purge the os2ShmNodeList list of all entries with nRef==0.
-**
-** This is not a VFS shared-memory method; it is a utility function called
-** by VFS shared-memory methods.
-*/
-static void os2PurgeShmNodes( int deleteFlag ) {
-  os2ShmNode *pNode;
-  os2ShmNode **ppNode;
-
-  os2ShmEnterMutex();
-  
-  ppNode = &os2ShmNodeList;
-
-  while( *ppNode ) {
-    pNode = *ppNode;
-
-    if( pNode->nRef == 0 ) {
-      *ppNode = pNode->pNext;   
-     
-      if( pNode->apRegion ) {
-        /* Prevent other processes from resizing the shared memory */
-        os2ShmSystemLock(pNode, _SHM_WRLCK_WAIT, OS2_SHM_DMS, 1);
-
-        while( pNode->nRegion-- ) {
-#ifdef SQLITE_DEBUG
-          int rc = 
-#endif          
-          DosFreeMem(pNode->apRegion[pNode->nRegion]);
-
-          OSTRACE(("SHM-PURGE pid-%d unmap region=%d %s\n",
-                  (int)GetCurrentProcessId(), pNode->nRegion,
-                  rc == 0 ? "ok" : "failed"));
-        }
-
-        /* Allow other processes to resize the shared memory */
-        os2ShmSystemLock(pNode, _SHM_UNLCK, OS2_SHM_DMS, 1);
-
-        sqlite3_free(pNode->apRegion);
-      }  
-
-      DosClose(pNode->hLockFile);
-      
-#ifndef SQLITE_OS2_NO_WAL_LOCK_FILE
-      if( deleteFlag ) {
-         char fileName[CCHMAXPATH];
-         /* Skip "\\SHAREMEM\\" */
-         sprintf(fileName, "%s-lck", pNode->shmBaseName + 10);
-         /* restore colon */
-         fileName[1] = ':';
-         
-         DosForceDelete(fileName); 
-      }
-#endif
-
-      sqlite3_mutex_free(pNode->mutex);
-
-      sqlite3_free(pNode);
-      
-    } else {
-      ppNode = &pNode->pNext;
-    }
-  } 
-
-  os2ShmLeaveMutex();
-}
-
-/*
-** This function is called to obtain a pointer to region iRegion of the
-** shared-memory associated with the database file id. 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 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 os2ShmMap(
-  sqlite3_file *id,               /* Handle open on database file */
-  int iRegion,                    /* Region to retrieve */
-  int szRegion,                   /* Size of regions */
-  int bExtend,                    /* True to extend block if necessary */
-  void volatile **pp              /* OUT: Mapped memory */
-){
-  PVOID pvTemp;
-  void **apRegion;
-  os2ShmNode *pNode;
-  int n, rc = SQLITE_OK;
-  char shmName[CCHMAXPATH];
-  os2File *pFile = (os2File*)id;
-  
-  *pp = NULL;
-
-  if( !pFile->pShmLink )
-    rc = os2OpenSharedMemory( pFile, szRegion );
-  
-  if( rc == SQLITE_OK ) {
-    pNode = pFile->pShmLink->pShmNode ;
-    
-    sqlite3_mutex_enter(pNode->mutex);
-    
-    assert( szRegion==pNode->szRegion );
-
-    /* Unmapped region ? */
-    if( iRegion >= pNode->nRegion ) {
-      /* Prevent other processes from resizing the shared memory */
-      os2ShmSystemLock(pNode, _SHM_WRLCK_WAIT, OS2_SHM_DMS, 1);
-
-      apRegion = sqlite3_realloc(
-        pNode->apRegion, (iRegion + 1) * sizeof(apRegion[0]));
-
-      if( apRegion ) {
-        pNode->apRegion = apRegion;
-
-        while( pNode->nRegion <= iRegion ) {
-          sprintf(shmName, "%s-%u", 
-                  pNode->shmBaseName, pNode->nRegion);
-
-          if( DosGetNamedSharedMem(&pvTemp, (PSZ)shmName, 
-                PAG_READ | PAG_WRITE) != NO_ERROR ) {
-            if( !bExtend )
-              break;
-
-            if( DosAllocSharedMem(&pvTemp, (PSZ)shmName, szRegion,
-                  PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_ANY) != NO_ERROR && 
-                DosAllocSharedMem(&pvTemp, (PSZ)shmName, szRegion,
-                  PAG_READ | PAG_WRITE | PAG_COMMIT) != NO_ERROR ) { 
-              rc = SQLITE_NOMEM;
-              break;
-            }
-          }
-
-          apRegion[pNode->nRegion++] = pvTemp;
-        }
-
-        /* zero out remaining entries */ 
-        for( n = pNode->nRegion; n <= iRegion; n++ )
-          pNode->apRegion[n] = NULL;
-
-        /* Return this region (maybe zero) */
-        *pp = pNode->apRegion[iRegion];
-      } else {
-        rc = SQLITE_NOMEM;
-      }
-
-      /* Allow other processes to resize the shared memory */
-      os2ShmSystemLock(pNode, _SHM_UNLCK, OS2_SHM_DMS, 1);
-      
-    } else {
-      /* Region has been mapped previously */
-      *pp = pNode->apRegion[iRegion];
-    }
-
-    sqlite3_mutex_leave(pNode->mutex);
-  } 
-
-  ERR_TRACE(rc, ("os2ShmMap: %s iRgn = %d, szRgn = %d, bExt = %d : %d\n", 
-                 pFile->zFullPathCp, iRegion, szRegion, bExtend, rc))
-          
-  return rc;
-}
-
-/*
-** 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 os2ShmUnmap(
-  sqlite3_file *id,               /* The underlying database file */
-  int deleteFlag                  /* Delete shared-memory if true */
-){
-  os2File *pFile = (os2File*)id;
-  os2ShmLink *pLink = pFile->pShmLink;
-  
-  if( pLink ) {
-    int nRef = -1;
-    os2ShmLink **ppLink;
-    os2ShmNode *pNode = pLink->pShmNode;
-
-    sqlite3_mutex_enter(pNode->mutex);
-    
-    for( ppLink = &pNode->pFirst;
-         *ppLink && *ppLink != pLink;
-         ppLink = &(*ppLink)->pNext )   ;
-         
-    assert(*ppLink);
-
-    if( *ppLink ) {
-      *ppLink = pLink->pNext;
-      nRef = --pNode->nRef;
-    } else {
-      ERR_TRACE(1, ("os2ShmUnmap: link not found ! %s\n", 
-                    pNode->shmBaseName))
-    }
-    
-    pFile->pShmLink = NULL;
-    sqlite3_free(pLink);
-
-    sqlite3_mutex_leave(pNode->mutex);
-    
-    if( nRef == 0 )
-      os2PurgeShmNodes( deleteFlag );
-  }
-
-  return SQLITE_OK;
-}
-
-/*
-** Change the lock state for a shared-memory segment.
-**
-** 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 os2ShmLock(
-  sqlite3_file *id,          /* 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 */
-){
-  u32 mask;                             /* Mask of locks to take or release */
-  int rc = SQLITE_OK;                   /* Result code */
-  os2File *pFile = (os2File*)id;
-  os2ShmLink *p = pFile->pShmLink;      /* The shared memory being locked */
-  os2ShmLink *pX;                       /* For looping over all siblings */
-  os2ShmNode *pShmNode = p->pShmNode;   /* Our node */
-  
-  assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
-  assert( n>=1 );
-  assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
-       || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
-       || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
-       || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
-  assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
-
-  mask = (u32)((1U<<(ofst+n)) - (1U<<ofst));
-  assert( n>1 || mask==(1<<ofst) );
-
-
-  sqlite3_mutex_enter(pShmNode->mutex);
-
-  if( flags & SQLITE_SHM_UNLOCK ){
-    u32 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 = os2ShmSystemLock(pShmNode, _SHM_UNLCK, ofst+OS2_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 ){
-    u32 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 = os2ShmSystemLock(pShmNode, _SHM_RDLCK, ofst+OS2_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 = os2ShmSystemLock(pShmNode, _SHM_WRLCK, ofst+OS2_SHM_BASE, n);
-      if( rc==SQLITE_OK ){
-        assert( (p->sharedMask & mask)==0 );
-        p->exclMask |= mask;
-      }
-    }
-  }
-
-  sqlite3_mutex_leave(pShmNode->mutex);
-  
-  OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x %s\n",
-           p->id, (int)GetCurrentProcessId(), p->sharedMask, p->exclMask,
-           rc ? "failed" : "ok"));
-
-  ERR_TRACE(rc, ("os2ShmLock: ofst = %d, n = %d, flags = 0x%x -> %d \n", 
-                 ofst, n, flags, rc))
-                  
-  return rc; 
-}
-
-/*
-** 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 os2ShmBarrier(
-  sqlite3_file *id                /* Database file holding the shared memory */
-){
-  UNUSED_PARAMETER(id);
-  os2ShmEnterMutex();
-  os2ShmLeaveMutex();
-}
-
-#else
-# define os2ShmMap     0
-# define os2ShmLock    0
-# define os2ShmBarrier 0
-# define os2ShmUnmap   0
-#endif /* #ifndef SQLITE_OMIT_WAL */
-
-
-/*
-** This vector defines all the methods that can operate on an
-** sqlite3_file for os2.
-*/
-static const sqlite3_io_methods os2IoMethod = {
-  2,                              /* iVersion */
-  os2Close,                       /* xClose */
-  os2Read,                        /* xRead */
-  os2Write,                       /* xWrite */
-  os2Truncate,                    /* xTruncate */
-  os2Sync,                        /* xSync */
-  os2FileSize,                    /* xFileSize */
-  os2Lock,                        /* xLock */
-  os2Unlock,                      /* xUnlock */
-  os2CheckReservedLock,           /* xCheckReservedLock */
-  os2FileControl,                 /* xFileControl */
-  os2SectorSize,                  /* xSectorSize */
-  os2DeviceCharacteristics,       /* xDeviceCharacteristics */
-  os2ShmMap,                      /* xShmMap */
-  os2ShmLock,                     /* xShmLock */
-  os2ShmBarrier,                  /* xShmBarrier */
-  os2ShmUnmap                     /* xShmUnmap */
-};
-
-
-/***************************************************************************
-** Here ends the I/O methods that form the sqlite3_io_methods object.
-**
-** The next block of code implements the VFS methods.
-****************************************************************************/
-
-/*
-** Create a temporary file name in zBuf.  zBuf must be big enough to
-** hold at pVfs->mxPathname characters.
-*/
-static int getTempname(int nBuf, char *zBuf ){
-  static const char zChars[] =
-    "abcdefghijklmnopqrstuvwxyz"
-    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-    "0123456789";
-  int i, j;
-  PSZ zTempPathCp;      
-  char zTempPath[CCHMAXPATH];
-  ULONG ulDriveNum, ulDriveMap;
-  
-  /* 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 );
-
-  if( sqlite3_temp_directory ) {
-    sqlite3_snprintf(CCHMAXPATH-30, zTempPath, "%s", sqlite3_temp_directory);
-  } else if( DosScanEnv( (PSZ)"TEMP",   &zTempPathCp ) == NO_ERROR ||
-             DosScanEnv( (PSZ)"TMP",    &zTempPathCp ) == NO_ERROR ||
-             DosScanEnv( (PSZ)"TMPDIR", &zTempPathCp ) == NO_ERROR ) {
-    char *zTempPathUTF = convertCpPathToUtf8( (char *)zTempPathCp );
-    sqlite3_snprintf(CCHMAXPATH-30, zTempPath, "%s", zTempPathUTF);
-    free( zTempPathUTF );
-  } else if( DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap ) == NO_ERROR ) {
-    zTempPath[0] = (char)('A' + ulDriveNum - 1);
-    zTempPath[1] = ':'; 
-    zTempPath[2] = '\0'; 
-  } else {
-    zTempPath[0] = '\0'; 
-  }
-  
-  /* Strip off a trailing slashes or backslashes, otherwise we would get *
-   * multiple (back)slashes which causes DosOpen() to fail.              *
-   * Trailing spaces are not allowed, either.                            */
-  j = sqlite3Strlen30(zTempPath);
-  while( j > 0 && ( zTempPath[j-1] == '\\' || zTempPath[j-1] == '/' || 
-                    zTempPath[j-1] == ' ' ) ){
-    j--;
-  }
-  zTempPath[j] = '\0';
-  
-  /* We use 20 bytes to randomize the name */
-  sqlite3_snprintf(nBuf-22, zBuf,
-                   "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath);
-  j = sqlite3Strlen30(zBuf);
-  sqlite3_randomness( 20, &zBuf[j] );
-  for( i = 0; i < 20; i++, j++ ){
-    zBuf[j] = zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
-  }
-  zBuf[j] = 0;
-
-  OSTRACE(( "TEMP FILENAME: %s\n", zBuf ));
-  return SQLITE_OK;
-}
-
-
-/*
-** Turn a relative pathname into a full pathname.  Write the full
-** pathname into zFull[].  zFull[] will be at least pVfs->mxPathname
-** bytes in size.
-*/
-static int os2FullPathname(
-  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 */
-){
-  char *zRelativeCp = convertUtf8PathToCp( zRelative );
-  char zFullCp[CCHMAXPATH] = "\0";
-  char *zFullUTF;
-  APIRET rc = DosQueryPathInfo( (PSZ)zRelativeCp, FIL_QUERYFULLNAME, 
-                                zFullCp, CCHMAXPATH );
-  free( zRelativeCp );
-  zFullUTF = convertCpPathToUtf8( zFullCp );
-  sqlite3_snprintf( nFull, zFull, zFullUTF );
-  free( zFullUTF );
-  return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
-}
-
-
-/*
-** Open a file.
-*/
-static int os2Open(
-  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 */
-){
-  HFILE h;
-  ULONG ulOpenFlags = 0;
-  ULONG ulOpenMode = 0;
-  ULONG ulAction = 0;
-  ULONG rc;
-  os2File *pFile = (os2File*)id;
-  const char *zUtf8Name = zName;
-  char *zNameCp;
-  char  zTmpname[CCHMAXPATH];
-
-  int isExclusive  = (flags & SQLITE_OPEN_EXCLUSIVE);
-  int isCreate     = (flags & SQLITE_OPEN_CREATE);
-  int isReadWrite  = (flags & SQLITE_OPEN_READWRITE);
-#ifndef NDEBUG
-  int isDelete     = (flags & SQLITE_OPEN_DELETEONCLOSE);
-  int isReadonly   = (flags & SQLITE_OPEN_READONLY);
-  int eType        = (flags & 0xFFFFFF00);
-  int isOpenJournal = (isCreate && (
-        eType==SQLITE_OPEN_MASTER_JOURNAL 
-     || eType==SQLITE_OPEN_MAIN_JOURNAL 
-     || eType==SQLITE_OPEN_WAL
-  ));
-#endif
-
-  UNUSED_PARAMETER(pVfs);
-  assert( id!=0 );
-
-  /* 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( pFile, 0, sizeof(*pFile) );
-  pFile->h = (HFILE)-1;
-
-  /* If the second argument to this function is NULL, generate a 
-  ** temporary file name to use 
-  */
-  if( !zUtf8Name ){
-    assert(isDelete && !isOpenJournal);
-    rc = getTempname(CCHMAXPATH, zTmpname);
-    if( rc!=SQLITE_OK ){
-      return rc;
-    }
-    zUtf8Name = zTmpname;
-  }
-
-  if( isReadWrite ){
-    ulOpenMode |= OPEN_ACCESS_READWRITE;
-  }else{
-    ulOpenMode |= OPEN_ACCESS_READONLY;
-  }
-
-  /* Open in random access mode for possibly better speed.  Allow full
-  ** sharing because file locks will provide exclusive access when needed.
-  ** The handle should not be inherited by child processes and we don't 
-  ** want popups from the critical error handler.
-  */
-  ulOpenMode |= OPEN_FLAGS_RANDOM | OPEN_SHARE_DENYNONE | 
-                OPEN_FLAGS_NOINHERIT | OPEN_FLAGS_FAIL_ON_ERROR;
-
-  /* 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. */
-    ulOpenFlags |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_FAIL_IF_EXISTS;
-  }else if( isCreate ){
-    /* Open existing file, or create if it doesn't exist */
-    ulOpenFlags |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
-  }else{
-    /* Opens a file, only if it exists. */
-    ulOpenFlags |= OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
-  }
-
-  zNameCp = convertUtf8PathToCp( zUtf8Name );
-  rc = DosOpen( (PSZ)zNameCp,
-                &h,
-                &ulAction,
-                0L,
-                FILE_NORMAL,
-                ulOpenFlags,
-                ulOpenMode,
-                (PEAOP2)NULL );
-  free( zNameCp );
-
-  if( rc != NO_ERROR ){
-    OSTRACE(( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulFlags=%#lx, ulMode=%#lx\n",
-              rc, zUtf8Name, ulAction, ulOpenFlags, ulOpenMode ));
-
-    if( isReadWrite ){
-      return os2Open( pVfs, zName, id,
-                      ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)),
-                      pOutFlags );
-    }else{
-      return SQLITE_CANTOPEN;
-    }
-  }
-
-  if( pOutFlags ){
-    *pOutFlags = isReadWrite ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY;
-  }
-
-  os2FullPathname( pVfs, zUtf8Name, sizeof( zTmpname ), zTmpname );
-  pFile->zFullPathCp = convertUtf8PathToCp( zTmpname );
-  pFile->pMethod = &os2IoMethod;
-  pFile->flags = flags;
-  pFile->h = h;
-
-  OpenCounter(+1);
-  OSTRACE(( "OPEN %d pOutFlags=%d\n", pFile->h, pOutFlags ));
-  return SQLITE_OK;
-}
-
-/*
-** Delete the named file.
-*/
-static int os2Delete(
-  sqlite3_vfs *pVfs,                     /* Not used on os2 */
-  const char *zFilename,                 /* Name of file to delete */
-  int syncDir                            /* Not used on os2 */
-){
-  APIRET rc;
-  char *zFilenameCp;
-  SimulateIOError( return SQLITE_IOERR_DELETE );
-  zFilenameCp = convertUtf8PathToCp( zFilename );
-  rc = DosDelete( (PSZ)zFilenameCp );
-  free( zFilenameCp );
-  OSTRACE(( "DELETE \"%s\"\n", zFilename ));
-  return (rc == NO_ERROR ||
-          rc == ERROR_FILE_NOT_FOUND ||
-          rc == ERROR_PATH_NOT_FOUND ) ? SQLITE_OK : SQLITE_IOERR_DELETE;
-}
-
-/*
-** Check the existance and status of a file.
-*/
-static int os2Access(
-  sqlite3_vfs *pVfs,        /* Not used on os2 */
-  const char *zFilename,    /* Name of file to check */
-  int flags,                /* Type of test to make on this file */
-  int *pOut                 /* Write results here */
-){
-  APIRET rc;
-  FILESTATUS3 fsts3ConfigInfo;
-  char *zFilenameCp;
-
-  UNUSED_PARAMETER(pVfs);
-  SimulateIOError( return SQLITE_IOERR_ACCESS; );
-  
-  zFilenameCp = convertUtf8PathToCp( zFilename );
-  rc = DosQueryPathInfo( (PSZ)zFilenameCp, FIL_STANDARD,
-                         &fsts3ConfigInfo, sizeof(FILESTATUS3) );
-  free( zFilenameCp );
-  OSTRACE(( "ACCESS fsts3ConfigInfo.attrFile=%d flags=%d rc=%d\n",
-            fsts3ConfigInfo.attrFile, flags, rc ));
-
-  switch( flags ){
-    case SQLITE_ACCESS_EXISTS:
-      /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file
-      ** as if it does not exist.
-      */
-      if( fsts3ConfigInfo.cbFile == 0 ) 
-        rc = ERROR_FILE_NOT_FOUND;
-      break;
-    case SQLITE_ACCESS_READ:
-      break;
-    case SQLITE_ACCESS_READWRITE:
-      if( fsts3ConfigInfo.attrFile & FILE_READONLY )
-        rc = ERROR_ACCESS_DENIED;
-      break;
-    default:
-      rc = ERROR_FILE_NOT_FOUND;
-      assert( !"Invalid flags argument" );
-  }
-
-  *pOut = (rc == NO_ERROR);
-  OSTRACE(( "ACCESS %s flags %d: rc=%d\n", zFilename, flags, *pOut ));
-
-  return SQLITE_OK;
-}
-
-
-#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.
-*/
-static void *os2DlOpen(sqlite3_vfs *pVfs, const char *zFilename){
-  HMODULE hmod;
-  APIRET rc;
-  char *zFilenameCp = convertUtf8PathToCp(zFilename);
-  rc = DosLoadModule(NULL, 0, (PSZ)zFilenameCp, &hmod);
-  free(zFilenameCp);
-  return rc != NO_ERROR ? 0 : (void*)hmod;
-}
-/*
-** A no-op since the error code is returned on the DosLoadModule call.
-** os2Dlopen returns zero if DosLoadModule is not successful.
-*/
-static void os2DlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
-/* no-op */
-}
-static void (*os2DlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
-  PFN pfn;
-  APIRET rc;
-  rc = DosQueryProcAddr((HMODULE)pHandle, 0L, (PSZ)zSymbol, &pfn);
-  if( rc != NO_ERROR ){
-    /* if the symbol itself was not found, search again for the same
-     * symbol with an extra underscore, that might be needed depending
-     * on the calling convention */
-    char _zSymbol[256] = "_";
-    strncat(_zSymbol, zSymbol, 254);
-    rc = DosQueryProcAddr((HMODULE)pHandle, 0L, (PSZ)_zSymbol, &pfn);
-  }
-  return rc != NO_ERROR ? 0 : (void(*)(void))pfn;
-}
-static void os2DlClose(sqlite3_vfs *pVfs, void *pHandle){
-  DosFreeModule((HMODULE)pHandle);
-}
-#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
-  #define os2DlOpen 0
-  #define os2DlError 0
-  #define os2DlSym 0
-  #define os2DlClose 0
-#endif
-
-
-/*
-** Write up to nBuf bytes of randomness into zBuf.
-*/
-static int os2Randomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf ){
-  int n = 0;
-#if defined(SQLITE_TEST)
-  n = nBuf;
-  memset(zBuf, 0, nBuf);
-#else
-  int i;                           
-  PPIB ppib;
-  PTIB ptib;
-  DATETIME dt; 
-  static unsigned c = 0;
-  /* Ordered by variation probability */
-  static ULONG svIdx[6] = { QSV_MS_COUNT, QSV_TIME_LOW,
-                            QSV_MAXPRMEM, QSV_MAXSHMEM,
-                            QSV_TOTAVAILMEM, QSV_TOTRESMEM };
-
-  /* 8 bytes; timezone and weekday don't increase the randomness much */
-  if( (int)sizeof(dt)-3 <= nBuf - n ){
-    c += 0x0100;
-    DosGetDateTime(&dt);
-    dt.year = (USHORT)((dt.year - 1900) | c);
-    memcpy(&zBuf[n], &dt, sizeof(dt)-3);
-    n += sizeof(dt)-3;
-  }
-
-  /* 4 bytes; PIDs and TIDs are 16 bit internally, so combine them */
-  if( (int)sizeof(ULONG) <= nBuf - n ){
-    DosGetInfoBlocks(&ptib, &ppib);
-    *(PULONG)&zBuf[n] = MAKELONG(ppib->pib_ulpid,
-                                 ptib->tib_ptib2->tib2_ultid);
-    n += sizeof(ULONG);
-  }
-
-  /* Up to 6 * 4 bytes; variables depend on the system state */
-  for( i = 0; i < 6 && (int)sizeof(ULONG) <= nBuf - n; i++ ){
-    DosQuerySysInfo(svIdx[i], svIdx[i], 
-                    (PULONG)&zBuf[n], sizeof(ULONG));
-    n += sizeof(ULONG);
-  } 
-#endif
-
-  return n;
-}
-
-/*
-** 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 os2Sleep( sqlite3_vfs *pVfs, int microsec ){
-  DosSleep( (microsec/1000) );
-  return microsec;
-}
-
-/*
-** The following variable, if set to a non-zero value, becomes the result
-** returned from sqlite3OsCurrentTime().  This is used for testing.
-*/
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_current_time = 0;
-#endif
-
-/*
-** 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 0.  Return 1 if the time and date cannot be found.
-*/
-static int os2CurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
-#ifdef SQLITE_TEST
-  static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
-#endif
-  int year, month, datepart, timepart;
-  DATETIME dt;
-  DosGetDateTime( &dt );
-
-  year = dt.year;
-  month = dt.month;
-
-  /* Calculations from http://www.astro.keele.ac.uk/~rno/Astronomy/hjd.html
-  ** http://www.astro.keele.ac.uk/~rno/Astronomy/hjd-0.1.c
-  ** Calculate the Julian days
-  */
-  datepart = (int)dt.day - 32076 +
-    1461*(year + 4800 + (month - 14)/12)/4 +
-    367*(month - 2 - (month - 14)/12*12)/12 -
-    3*((year + 4900 + (month - 14)/12)/100)/4;
-
-  /* Time in milliseconds, hours to noon added */
-  timepart = 12*3600*1000 + dt.hundredths*10 + dt.seconds*1000 +
-    ((int)dt.minutes + dt.timezone)*60*1000 + dt.hours*3600*1000;
-
-  *piNow = (sqlite3_int64)datepart*86400*1000 + timepart;
-   
-#ifdef SQLITE_TEST
-  if( sqlite3_current_time ){
-    *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
-  }
-#endif
-
-  UNUSED_PARAMETER(pVfs);
-  return 0;
-}
-
-/*
-** 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 os2CurrentTime( sqlite3_vfs *pVfs, double *prNow ){
-  int rc;
-  sqlite3_int64 i;
-  rc = os2CurrentTimeInt64(pVfs, &i);
-  if( !rc ){
-    *prNow = i/86400000.0;
-  }
-  return rc;
-}
-
-/*
-** The idea is that this function works like a combination of
-** GetLastError() and FormatMessage() on windows (or errno and
-** strerror_r() on unix). After an error is returned by an OS
-** function, SQLite calls this function with zBuf pointing to
-** a buffer of nBuf bytes. The OS layer should populate the
-** buffer with a nul-terminated UTF-8 encoded error message
-** describing the last IO error to have occurred within the calling
-** thread.
-**
-** If the error message is too large for the supplied buffer,
-** it should be truncated. The return value of xGetLastError
-** is zero if the error message fits in the buffer, or non-zero
-** otherwise (if the message was truncated). If non-zero is returned,
-** then it is not necessary to include the nul-terminator character
-** in the output buffer.
-**
-** Not supplying an error message will have no adverse effect
-** on SQLite. It is fine to have an implementation that never
-** returns an error message:
-**
-**   int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
-**     assert(zBuf[0]=='\0');
-**     return 0;
-**   }
-**
-** However if an error message is supplied, it will be incorporated
-** by sqlite into the error message available to the user using
-** sqlite3_errmsg(), possibly making IO errors easier to debug.
-*/
-static int os2GetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
-  assert(zBuf[0]=='\0');
-  return 0;
-}
-
-/*
-** Initialize and deinitialize the operating system interface.
-*/
-SQLITE_API int sqlite3_os_init(void){
-  static sqlite3_vfs os2Vfs = {
-    3,                 /* iVersion */
-    sizeof(os2File),   /* szOsFile */
-    CCHMAXPATH,        /* mxPathname */
-    0,                 /* pNext */
-    "os2",             /* zName */
-    0,                 /* pAppData */
-
-    os2Open,           /* xOpen */
-    os2Delete,         /* xDelete */
-    os2Access,         /* xAccess */
-    os2FullPathname,   /* xFullPathname */
-    os2DlOpen,         /* xDlOpen */
-    os2DlError,        /* xDlError */
-    os2DlSym,          /* xDlSym */
-    os2DlClose,        /* xDlClose */
-    os2Randomness,     /* xRandomness */
-    os2Sleep,          /* xSleep */
-    os2CurrentTime,    /* xCurrentTime */
-    os2GetLastError,   /* xGetLastError */
-    os2CurrentTimeInt64, /* xCurrentTimeInt64 */
-    0,                 /* xSetSystemCall */
-    0,                 /* xGetSystemCall */
-    0                  /* xNextSystemCall */
-  };
-  sqlite3_vfs_register(&os2Vfs, 1);
-  initUconvObjects();
-/*  sqlite3OSTrace = 1; */
-  return SQLITE_OK;
-}
-SQLITE_API int sqlite3_os_end(void){
-  freeUconvObjects();
-  return SQLITE_OK;
-}
-
-#endif /* SQLITE_OS_OS2 */
-
-/************** End of os_os2.c **********************************************/
 /************** Begin file os_unix.c *****************************************/
 /*
 ** 2004 May 22
@@ -24966,6 +22714,17 @@ SQLITE_API int sqlite3_os_end(void){
 */
 #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
+
+#ifdef __UCLIBC__
+  #undef HAVE_POSIX_FALLOCATE
+#endif
+
 /*
 ** There are various methods for file locking used for concurrency
 ** control:
@@ -25138,6 +22897,10 @@ struct unixFile {
   const char *zPath;                  /* Name of the file */
   unixShm *pShm;                      /* Shared memory segment information */
   int szChunk;                        /* Configured by FCNTL_CHUNK_SIZE */
+#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
@@ -25843,9 +23606,9 @@ static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) {
   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) ){
+        (sqliteIOErr == SQLITE_IOERR_UNLOCK) || 
+        (sqliteIOErr == SQLITE_IOERR_RDLOCK) ||
+        (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ){
       return SQLITE_BUSY;
     }
     /* else fall through */
@@ -26180,7 +23943,7 @@ static unixInodeInfo *inodeList = 0;
 ** 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 the associated file-system path,
+** failed (e.g. "unlink", "open") and the associated file-system path,
 ** if any.
 */
 #define unixLogError(a,b,c)     unixLogErrorAtLine(a,b,c,__LINE__)
@@ -26203,7 +23966,7 @@ static int unixLogErrorAtLine(
   zErr = aErr;
 
   /* If STRERROR_R_CHAR_P (set by autoconf scripts) or __USE_GNU is defined,
-  ** assume that the system provides the the GNU version of strerror_r() that 
+  ** 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 
@@ -26892,7 +24655,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
         pInode->eFileLock = NO_LOCK;
       }else{
         rc = SQLITE_IOERR_UNLOCK;
-       pFile->lastErrno = errno;
+        pFile->lastErrno = errno;
         pInode->eFileLock = NO_LOCK;
         pFile->eFileLock = NO_LOCK;
       }
@@ -26908,7 +24671,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
       closePendingFds(pFile);
     }
   }
-       
+
 end_unlock:
   unixLeaveMutex();
   if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock;
@@ -27175,7 +24938,7 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
 
   assert( pFile );
   OSTRACE(("UNLOCK  %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock,
-          pFile->eFileLock, getpid()));
+           pFile->eFileLock, getpid()));
   assert( eFileLock<=SHARED_LOCK );
   
   /* no-op if possible */
@@ -27214,13 +24977,13 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
 ** Close a file.  Make sure the lock has been released before closing.
 */
 static int dotlockClose(sqlite3_file *id) {
-  int rc;
+  int rc = SQLITE_OK;
   if( id ){
     unixFile *pFile = (unixFile*)id;
     dotlockUnlock(id, NO_LOCK);
     sqlite3_free(pFile->lockingContext);
+    rc = closeUnixFile(id);
   }
-  rc = closeUnixFile(id);
   return rc;
 }
 /****************** End of the dot-file lock implementation *******************
@@ -27424,10 +25187,12 @@ static int flockUnlock(sqlite3_file *id, int eFileLock) {
 ** Close a file.
 */
 static int flockClose(sqlite3_file *id) {
+  int rc = SQLITE_OK;
   if( id ){
     flockUnlock(id, NO_LOCK);
+    rc = closeUnixFile(id);
   }
-  return closeUnixFile(id);
+  return rc;
 }
 
 #endif /* SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORK */
@@ -27562,7 +25327,7 @@ static int semUnlock(sqlite3_file *id, int eFileLock) {
   assert( pFile );
   assert( pSem );
   OSTRACE(("UNLOCK  %d %d was %d pid=%d (sem)\n", pFile->h, eFileLock,
-          pFile->eFileLock, getpid()));
+           pFile->eFileLock, getpid()));
   assert( eFileLock<=SHARED_LOCK );
   
   /* no-op if possible */
@@ -28138,6 +25903,8 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
   i64 newOffset;
 #endif
   TIMER_START;
+  assert( cnt==(cnt&0x1ffff) );
+  cnt &= 0x1ffff;
   do{
 #if defined(USE_PREAD)
     got = osPread(id->h, pBuf, cnt, offset);
@@ -28152,7 +25919,7 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
       if( newOffset == -1 ){
         ((unixFile*)id)->lastErrno = errno;
       }else{
-        ((unixFile*)id)->lastErrno = 0;                        
+        ((unixFile*)id)->lastErrno = 0;
       }
       return -1;
     }
@@ -28227,6 +25994,8 @@ static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){
 #if (!defined(USE_PREAD) && !defined(USE_PREAD64))
   i64 newOffset;
 #endif
+  assert( cnt==(cnt&0x1ffff) );
+  cnt &= 0x1ffff;
   TIMER_START;
 #if defined(USE_PREAD)
   do{ got = osPwrite(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR );
@@ -28240,7 +26009,7 @@ static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){
       if( newOffset == -1 ){
         ((unixFile*)id)->lastErrno = errno;
       }else{
-        ((unixFile*)id)->lastErrno = 0;                        
+        ((unixFile*)id)->lastErrno = 0;
       }
       return -1;
     }
@@ -28692,6 +26461,9 @@ static void unixModeBit(unixFile *pFile, unsigned char mask, int *pArg){
   }
 }
 
+/* Forward declaration */
+static int unixGetTempname(int nBuf, char *zBuf);
+
 /*
 ** Information and control of an open file handle.
 */
@@ -28729,6 +26501,14 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
       *(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;
+    }
 #ifdef SQLITE_DEBUG
     /* The pager calls this method to signal that it has done
     ** a rollback and that the database is therefore unchanged and
@@ -28760,10 +26540,92 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
 ** a database and its journal file) that the sector size will be the
 ** same for both.
 */
-static int unixSectorSize(sqlite3_file *pFile){
-  (void)pFile;
+#ifndef __QNXNTO__ 
+static int unixSectorSize(sqlite3_file *NotUsed){
+  UNUSED_PARAMETER(NotUsed);
   return SQLITE_DEFAULT_SECTOR_SIZE;
 }
+#endif
+
+/*
+** 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;
+    }
+
+    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;
+}
+#endif /* __QNXNTO__ */
 
 /*
 ** Return the device characteristics for the file.
@@ -28780,11 +26642,15 @@ static int unixSectorSize(sqlite3_file *pFile){
 */
 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 ){
-    return SQLITE_IOCAP_POWERSAFE_OVERWRITE;
-  }else{
-    return 0;
+    rc |= SQLITE_IOCAP_POWERSAFE_OVERWRITE;
   }
+  return rc;
 }
 
 #ifndef SQLITE_OMIT_WAL
@@ -29200,11 +27066,19 @@ static int unixShmMap(
         ** the requested memory region.
         */
         if( !bExtend ) goto shmpage_out;
+#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
+        if( osFallocate(pShmNode->h, sStat.st_size, nByte)!=0 ){
+          rc = unixLogError(SQLITE_IOERR_SHMSIZE, "fallocate",
+                            pShmNode->zFilename);
+          goto shmpage_out;
+        }
+#else
         if( robust_ftruncate(pShmNode->h, nByte) ){
           rc = unixLogError(SQLITE_IOERR_SHMSIZE, "ftruncate",
                             pShmNode->zFilename);
           goto shmpage_out;
         }
+#endif
       }
     }
 
@@ -29222,7 +27096,7 @@ static int unixShmMap(
       if( pShmNode->h>=0 ){
         pMem = mmap(0, szRegion,
             pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, 
-            MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion
+            MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
         );
         if( pMem==MAP_FAILED ){
           rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename);
@@ -30406,8 +28280,13 @@ static int unixDelete(
   int rc = SQLITE_OK;
   UNUSED_PARAMETER(NotUsed);
   SimulateIOError(return SQLITE_IOERR_DELETE);
-  if( osUnlink(zPath)==(-1) && errno!=ENOENT ){
-    return unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath);
+  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 ){
@@ -30754,7 +28633,7 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
 ** address in the shared range is taken for a SHARED lock, the entire
 ** shared range is taken for an EXCLUSIVE lock):
 **
-**      PENDING_BYTE        0x40000000                 
+**      PENDING_BYTE        0x40000000
 **      RESERVED_BYTE       0x40000001
 **      SHARED_RANGE        0x40000002 -> 0x40000200
 **
@@ -32252,6 +30131,66 @@ SQLITE_API int sqlite3_open_file_count = 0;
 /************** 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.
+*/
+#if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL)
+# error "WAL mode requires support from the Windows NT kernel, compile\
+ with SQLITE_OMIT_WAL."
+#endif
+
+/*
+** 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
+
+/*
+** 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
+
+/*
+** 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);
+
+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) */
+
+#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 */
+
+/*
+** 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) */
+
 /*
 ** Macro to find the minimum of two numeric values.
 */
@@ -32274,9 +30213,11 @@ SQLITE_API int sqlite3_open_file_count = 0;
 # define FILE_ATTRIBUTE_MASK     (0x0003FFF7)
 #endif
 
+#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
 
 /*
 ** WinCE lacks native support for file locking so we have to fake it
@@ -32304,7 +30245,9 @@ struct winFile {
   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
@@ -32329,6 +30272,22 @@ struct winFile {
 #  define SQLITE_WIN32_DBG_BUF_SIZE   ((int)(4096-sizeof(DWORD)))
 #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
+
+/*
+ * 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
+
 /*
  * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the
  * various Win32 API heap functions instead of our own.
@@ -32437,14 +30396,6 @@ SQLITE_API int sqlite3_os_type = 0;
 static int sqlite3_os_type = 0;
 #endif
 
-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
-#  define SQLITE_WIN32_HAS_ANSI
-#endif
-
-#if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT
-#  define SQLITE_WIN32_HAS_WIDE
-#endif
-
 #ifndef SYSCALL
 #  define SYSCALL sqlite3_syscall_ptr
 #endif
@@ -32516,14 +30467,25 @@ static struct win_syscall {
 #define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \
         LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)
 
-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
+#if (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \
+        !defined(SQLITE_OMIT_WAL))
+  { "CreateFileMappingA",      (SYSCALL)CreateFileMappingA,      0 },
+#else
+  { "CreateFileMappingA",      (SYSCALL)0,                       0 },
+#endif
+
+#define osCreateFileMappingA ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
+        DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent)
+
+#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
+        !defined(SQLITE_OMIT_WAL))
   { "CreateFileMappingW",      (SYSCALL)CreateFileMappingW,      0 },
 #else
   { "CreateFileMappingW",      (SYSCALL)0,                       0 },
 #endif
 
 #define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
-        DWORD,DWORD,DWORD,LPCWSTR))aSyscall[6].pCurrent)
+        DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent)
 
 #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
   { "CreateMutexW",            (SYSCALL)CreateMutexW,            0 },
@@ -32532,7 +30494,7 @@ static struct win_syscall {
 #endif
 
 #define osCreateMutexW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,BOOL, \
-        LPCWSTR))aSyscall[7].pCurrent)
+        LPCWSTR))aSyscall[8].pCurrent)
 
 #if defined(SQLITE_WIN32_HAS_ANSI)
   { "DeleteFileA",             (SYSCALL)DeleteFileA,             0 },
@@ -32540,7 +30502,7 @@ static struct win_syscall {
   { "DeleteFileA",             (SYSCALL)0,                       0 },
 #endif
 
-#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[8].pCurrent)
+#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[9].pCurrent)
 
 #if defined(SQLITE_WIN32_HAS_WIDE)
   { "DeleteFileW",             (SYSCALL)DeleteFileW,             0 },
@@ -32548,7 +30510,7 @@ static struct win_syscall {
   { "DeleteFileW",             (SYSCALL)0,                       0 },
 #endif
 
-#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[9].pCurrent)
+#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[10].pCurrent)
 
 #if SQLITE_OS_WINCE
   { "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 },
@@ -32557,7 +30519,7 @@ static struct win_syscall {
 #endif
 
 #define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(CONST FILETIME*, \
-        LPFILETIME))aSyscall[10].pCurrent)
+        LPFILETIME))aSyscall[11].pCurrent)
 
 #if SQLITE_OS_WINCE
   { "FileTimeToSystemTime",    (SYSCALL)FileTimeToSystemTime,    0 },
@@ -32566,11 +30528,11 @@ static struct win_syscall {
 #endif
 
 #define osFileTimeToSystemTime ((BOOL(WINAPI*)(CONST FILETIME*, \
-        LPSYSTEMTIME))aSyscall[11].pCurrent)
+        LPSYSTEMTIME))aSyscall[12].pCurrent)
 
   { "FlushFileBuffers",        (SYSCALL)FlushFileBuffers,        0 },
 
-#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[12].pCurrent)
+#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[13].pCurrent)
 
 #if defined(SQLITE_WIN32_HAS_ANSI)
   { "FormatMessageA",          (SYSCALL)FormatMessageA,          0 },
@@ -32579,7 +30541,7 @@ static struct win_syscall {
 #endif
 
 #define osFormatMessageA ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPSTR, \
-        DWORD,va_list*))aSyscall[13].pCurrent)
+        DWORD,va_list*))aSyscall[14].pCurrent)
 
 #if defined(SQLITE_WIN32_HAS_WIDE)
   { "FormatMessageW",          (SYSCALL)FormatMessageW,          0 },
@@ -32588,15 +30550,19 @@ static struct win_syscall {
 #endif
 
 #define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \
-        DWORD,va_list*))aSyscall[14].pCurrent)
+        DWORD,va_list*))aSyscall[15].pCurrent)
 
+#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
   { "FreeLibrary",             (SYSCALL)FreeLibrary,             0 },
+#else
+  { "FreeLibrary",             (SYSCALL)0,                       0 },
+#endif
 
-#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[15].pCurrent)
+#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent)
 
   { "GetCurrentProcessId",     (SYSCALL)GetCurrentProcessId,     0 },
 
-#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[16].pCurrent)
+#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[17].pCurrent)
 
 #if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
   { "GetDiskFreeSpaceA",       (SYSCALL)GetDiskFreeSpaceA,       0 },
@@ -32605,7 +30571,7 @@ static struct win_syscall {
 #endif
 
 #define osGetDiskFreeSpaceA ((BOOL(WINAPI*)(LPCSTR,LPDWORD,LPDWORD,LPDWORD, \
-        LPDWORD))aSyscall[17].pCurrent)
+        LPDWORD))aSyscall[18].pCurrent)
 
 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
   { "GetDiskFreeSpaceW",       (SYSCALL)GetDiskFreeSpaceW,       0 },
@@ -32614,7 +30580,7 @@ static struct win_syscall {
 #endif
 
 #define osGetDiskFreeSpaceW ((BOOL(WINAPI*)(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, \
-        LPDWORD))aSyscall[18].pCurrent)
+        LPDWORD))aSyscall[19].pCurrent)
 
 #if defined(SQLITE_WIN32_HAS_ANSI)
   { "GetFileAttributesA",      (SYSCALL)GetFileAttributesA,      0 },
@@ -32622,7 +30588,7 @@ static struct win_syscall {
   { "GetFileAttributesA",      (SYSCALL)0,                       0 },
 #endif
 
-#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[19].pCurrent)
+#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[20].pCurrent)
 
 #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
   { "GetFileAttributesW",      (SYSCALL)GetFileAttributesW,      0 },
@@ -32630,7 +30596,7 @@ static struct win_syscall {
   { "GetFileAttributesW",      (SYSCALL)0,                       0 },
 #endif
 
-#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[20].pCurrent)
+#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[21].pCurrent)
 
 #if defined(SQLITE_WIN32_HAS_WIDE)
   { "GetFileAttributesExW",    (SYSCALL)GetFileAttributesExW,    0 },
@@ -32639,7 +30605,7 @@ static struct win_syscall {
 #endif
 
 #define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \
-        LPVOID))aSyscall[21].pCurrent)
+        LPVOID))aSyscall[22].pCurrent)
 
 #if !SQLITE_OS_WINRT
   { "GetFileSize",             (SYSCALL)GetFileSize,             0 },
@@ -32647,7 +30613,7 @@ static struct win_syscall {
   { "GetFileSize",             (SYSCALL)0,                       0 },
 #endif
 
-#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[22].pCurrent)
+#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[23].pCurrent)
 
 #if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
   { "GetFullPathNameA",        (SYSCALL)GetFullPathNameA,        0 },
@@ -32656,7 +30622,7 @@ static struct win_syscall {
 #endif
 
 #define osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \
-        LPSTR*))aSyscall[23].pCurrent)
+        LPSTR*))aSyscall[24].pCurrent)
 
 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
   { "GetFullPathNameW",        (SYSCALL)GetFullPathNameW,        0 },
@@ -32665,12 +30631,13 @@ static struct win_syscall {
 #endif
 
 #define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \
-        LPWSTR*))aSyscall[24].pCurrent)
+        LPWSTR*))aSyscall[25].pCurrent)
 
   { "GetLastError",            (SYSCALL)GetLastError,            0 },
 
-#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[25].pCurrent)
+#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 },
@@ -32679,9 +30646,12 @@ static struct win_syscall {
   ** 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[26].pCurrent)
+        LPCSTR))aSyscall[27].pCurrent)
 
 #if !SQLITE_OS_WINRT
   { "GetSystemInfo",           (SYSCALL)GetSystemInfo,           0 },
@@ -32689,11 +30659,11 @@ static struct win_syscall {
   { "GetSystemInfo",           (SYSCALL)0,                       0 },
 #endif
 
-#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[27].pCurrent)
+#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[28].pCurrent)
 
   { "GetSystemTime",           (SYSCALL)GetSystemTime,           0 },
 
-#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[28].pCurrent)
+#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[29].pCurrent)
 
 #if !SQLITE_OS_WINCE
   { "GetSystemTimeAsFileTime", (SYSCALL)GetSystemTimeAsFileTime, 0 },
@@ -32702,7 +30672,7 @@ static struct win_syscall {
 #endif
 
 #define osGetSystemTimeAsFileTime ((VOID(WINAPI*)( \
-        LPFILETIME))aSyscall[29].pCurrent)
+        LPFILETIME))aSyscall[30].pCurrent)
 
 #if defined(SQLITE_WIN32_HAS_ANSI)
   { "GetTempPathA",            (SYSCALL)GetTempPathA,            0 },
@@ -32710,7 +30680,7 @@ static struct win_syscall {
   { "GetTempPathA",            (SYSCALL)0,                       0 },
 #endif
 
-#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[30].pCurrent)
+#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[31].pCurrent)
 
 #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
   { "GetTempPathW",            (SYSCALL)GetTempPathW,            0 },
@@ -32718,7 +30688,7 @@ static struct win_syscall {
   { "GetTempPathW",            (SYSCALL)0,                       0 },
 #endif
 
-#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[31].pCurrent)
+#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[32].pCurrent)
 
 #if !SQLITE_OS_WINRT
   { "GetTickCount",            (SYSCALL)GetTickCount,            0 },
@@ -32726,7 +30696,7 @@ static struct win_syscall {
   { "GetTickCount",            (SYSCALL)0,                       0 },
 #endif
 
-#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[32].pCurrent)
+#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent)
 
 #if defined(SQLITE_WIN32_HAS_ANSI)
   { "GetVersionExA",           (SYSCALL)GetVersionExA,           0 },
@@ -32735,12 +30705,12 @@ static struct win_syscall {
 #endif
 
 #define osGetVersionExA ((BOOL(WINAPI*)( \
-        LPOSVERSIONINFOA))aSyscall[33].pCurrent)
+        LPOSVERSIONINFOA))aSyscall[34].pCurrent)
 
   { "HeapAlloc",               (SYSCALL)HeapAlloc,               0 },
 
 #define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \
-        SIZE_T))aSyscall[34].pCurrent)
+        SIZE_T))aSyscall[35].pCurrent)
 
 #if !SQLITE_OS_WINRT
   { "HeapCreate",              (SYSCALL)HeapCreate,              0 },
@@ -32749,7 +30719,7 @@ static struct win_syscall {
 #endif
 
 #define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \
-        SIZE_T))aSyscall[35].pCurrent)
+        SIZE_T))aSyscall[36].pCurrent)
 
 #if !SQLITE_OS_WINRT
   { "HeapDestroy",             (SYSCALL)HeapDestroy,             0 },
@@ -32757,21 +30727,21 @@ static struct win_syscall {
   { "HeapDestroy",             (SYSCALL)0,                       0 },
 #endif
 
-#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[36].pCurrent)
+#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[37].pCurrent)
 
   { "HeapFree",                (SYSCALL)HeapFree,                0 },
 
-#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[37].pCurrent)
+#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[38].pCurrent)
 
   { "HeapReAlloc",             (SYSCALL)HeapReAlloc,             0 },
 
 #define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \
-        SIZE_T))aSyscall[38].pCurrent)
+        SIZE_T))aSyscall[39].pCurrent)
 
   { "HeapSize",                (SYSCALL)HeapSize,                0 },
 
 #define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \
-        LPCVOID))aSyscall[39].pCurrent)
+        LPCVOID))aSyscall[40].pCurrent)
 
 #if !SQLITE_OS_WINRT
   { "HeapValidate",            (SYSCALL)HeapValidate,            0 },
@@ -32780,23 +30750,24 @@ static struct win_syscall {
 #endif
 
 #define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \
-        LPCVOID))aSyscall[40].pCurrent)
+        LPCVOID))aSyscall[41].pCurrent)
 
-#if defined(SQLITE_WIN32_HAS_ANSI)
+#if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
   { "LoadLibraryA",            (SYSCALL)LoadLibraryA,            0 },
 #else
   { "LoadLibraryA",            (SYSCALL)0,                       0 },
 #endif
 
-#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[41].pCurrent)
+#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[42].pCurrent)
 
-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
+        !defined(SQLITE_OMIT_LOAD_EXTENSION)
   { "LoadLibraryW",            (SYSCALL)LoadLibraryW,            0 },
 #else
   { "LoadLibraryW",            (SYSCALL)0,                       0 },
 #endif
 
-#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[42].pCurrent)
+#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[43].pCurrent)
 
 #if !SQLITE_OS_WINRT
   { "LocalFree",               (SYSCALL)LocalFree,               0 },
@@ -32804,7 +30775,7 @@ static struct win_syscall {
   { "LocalFree",               (SYSCALL)0,                       0 },
 #endif
 
-#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[43].pCurrent)
+#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[44].pCurrent)
 
 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
   { "LockFile",                (SYSCALL)LockFile,                0 },
@@ -32814,7 +30785,7 @@ static struct win_syscall {
 
 #ifndef osLockFile
 #define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
-        DWORD))aSyscall[44].pCurrent)
+        DWORD))aSyscall[45].pCurrent)
 #endif
 
 #if !SQLITE_OS_WINCE
@@ -32825,36 +30796,36 @@ static struct win_syscall {
 
 #ifndef osLockFileEx
 #define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \
-        LPOVERLAPPED))aSyscall[45].pCurrent)
+        LPOVERLAPPED))aSyscall[46].pCurrent)
 #endif
 
-#if !SQLITE_OS_WINRT
+#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL))
   { "MapViewOfFile",           (SYSCALL)MapViewOfFile,           0 },
 #else
   { "MapViewOfFile",           (SYSCALL)0,                       0 },
 #endif
 
 #define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
-        SIZE_T))aSyscall[46].pCurrent)
+        SIZE_T))aSyscall[47].pCurrent)
 
   { "MultiByteToWideChar",     (SYSCALL)MultiByteToWideChar,     0 },
 
 #define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \
-        int))aSyscall[47].pCurrent)
+        int))aSyscall[48].pCurrent)
 
   { "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 },
 
 #define osQueryPerformanceCounter ((BOOL(WINAPI*)( \
-        LARGE_INTEGER*))aSyscall[48].pCurrent)
+        LARGE_INTEGER*))aSyscall[49].pCurrent)
 
   { "ReadFile",                (SYSCALL)ReadFile,                0 },
 
 #define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \
-        LPOVERLAPPED))aSyscall[49].pCurrent)
+        LPOVERLAPPED))aSyscall[50].pCurrent)
 
   { "SetEndOfFile",            (SYSCALL)SetEndOfFile,            0 },
 
-#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[50].pCurrent)
+#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[51].pCurrent)
 
 #if !SQLITE_OS_WINRT
   { "SetFilePointer",          (SYSCALL)SetFilePointer,          0 },
@@ -32863,7 +30834,7 @@ static struct win_syscall {
 #endif
 
 #define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \
-        DWORD))aSyscall[51].pCurrent)
+        DWORD))aSyscall[52].pCurrent)
 
 #if !SQLITE_OS_WINRT
   { "Sleep",                   (SYSCALL)Sleep,                   0 },
@@ -32871,12 +30842,12 @@ static struct win_syscall {
   { "Sleep",                   (SYSCALL)0,                       0 },
 #endif
 
-#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[52].pCurrent)
+#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[53].pCurrent)
 
   { "SystemTimeToFileTime",    (SYSCALL)SystemTimeToFileTime,    0 },
 
 #define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \
-        LPFILETIME))aSyscall[53].pCurrent)
+        LPFILETIME))aSyscall[54].pCurrent)
 
 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
   { "UnlockFile",              (SYSCALL)UnlockFile,              0 },
@@ -32886,7 +30857,7 @@ static struct win_syscall {
 
 #ifndef osUnlockFile
 #define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
-        DWORD))aSyscall[54].pCurrent)
+        DWORD))aSyscall[55].pCurrent)
 #endif
 
 #if !SQLITE_OS_WINCE
@@ -32896,21 +30867,25 @@ static struct win_syscall {
 #endif
 
 #define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
-        LPOVERLAPPED))aSyscall[55].pCurrent)
+        LPOVERLAPPED))aSyscall[56].pCurrent)
 
+#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL)
   { "UnmapViewOfFile",         (SYSCALL)UnmapViewOfFile,         0 },
+#else
+  { "UnmapViewOfFile",         (SYSCALL)0,                       0 },
+#endif
 
-#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[56].pCurrent)
+#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[57].pCurrent)
+        LPCSTR,LPBOOL))aSyscall[58].pCurrent)
 
   { "WriteFile",               (SYSCALL)WriteFile,               0 },
 
 #define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \
-        LPOVERLAPPED))aSyscall[58].pCurrent)
+        LPOVERLAPPED))aSyscall[59].pCurrent)
 
 #if SQLITE_OS_WINRT
   { "CreateEventExW",          (SYSCALL)CreateEventExW,          0 },
@@ -32919,7 +30894,7 @@ static struct win_syscall {
 #endif
 
 #define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \
-        DWORD,DWORD))aSyscall[59].pCurrent)
+        DWORD,DWORD))aSyscall[60].pCurrent)
 
 #if !SQLITE_OS_WINRT
   { "WaitForSingleObject",     (SYSCALL)WaitForSingleObject,     0 },
@@ -32928,25 +30903,25 @@ static struct win_syscall {
 #endif
 
 #define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
-        DWORD))aSyscall[60].pCurrent)
+        DWORD))aSyscall[61].pCurrent)
 
-#if !SQLITE_OS_WINCE
+#if SQLITE_OS_WINRT
   { "WaitForSingleObjectEx",   (SYSCALL)WaitForSingleObjectEx,   0 },
 #else
   { "WaitForSingleObjectEx",   (SYSCALL)0,                       0 },
 #endif
 
 #define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
-        BOOL))aSyscall[61].pCurrent)
+        BOOL))aSyscall[62].pCurrent)
 
-#if !SQLITE_OS_WINCE
+#if SQLITE_OS_WINRT
   { "SetFilePointerEx",        (SYSCALL)SetFilePointerEx,        0 },
 #else
   { "SetFilePointerEx",        (SYSCALL)0,                       0 },
 #endif
 
 #define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \
-        PLARGE_INTEGER,DWORD))aSyscall[62].pCurrent)
+        PLARGE_INTEGER,DWORD))aSyscall[63].pCurrent)
 
 #if SQLITE_OS_WINRT
   { "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 },
@@ -32955,16 +30930,16 @@ static struct win_syscall {
 #endif
 
 #define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
-        FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[63].pCurrent)
+        FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[64].pCurrent)
 
-#if SQLITE_OS_WINRT
+#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
   { "MapViewOfFileFromApp",    (SYSCALL)MapViewOfFileFromApp,    0 },
 #else
   { "MapViewOfFileFromApp",    (SYSCALL)0,                       0 },
 #endif
 
 #define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \
-        SIZE_T))aSyscall[64].pCurrent)
+        SIZE_T))aSyscall[65].pCurrent)
 
 #if SQLITE_OS_WINRT
   { "CreateFile2",             (SYSCALL)CreateFile2,             0 },
@@ -32973,16 +30948,16 @@ static struct win_syscall {
 #endif
 
 #define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \
-        LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[65].pCurrent)
+        LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[66].pCurrent)
 
-#if SQLITE_OS_WINRT
+#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION)
   { "LoadPackagedLibrary",     (SYSCALL)LoadPackagedLibrary,     0 },
 #else
   { "LoadPackagedLibrary",     (SYSCALL)0,                       0 },
 #endif
 
 #define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \
-        DWORD))aSyscall[66].pCurrent)
+        DWORD))aSyscall[67].pCurrent)
 
 #if SQLITE_OS_WINRT
   { "GetTickCount64",          (SYSCALL)GetTickCount64,          0 },
@@ -32990,7 +30965,7 @@ static struct win_syscall {
   { "GetTickCount64",          (SYSCALL)0,                       0 },
 #endif
 
-#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[67].pCurrent)
+#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[68].pCurrent)
 
 #if SQLITE_OS_WINRT
   { "GetNativeSystemInfo",     (SYSCALL)GetNativeSystemInfo,     0 },
@@ -32999,7 +30974,7 @@ static struct win_syscall {
 #endif
 
 #define osGetNativeSystemInfo ((VOID(WINAPI*)( \
-        LPSYSTEM_INFO))aSyscall[68].pCurrent)
+        LPSYSTEM_INFO))aSyscall[69].pCurrent)
 
 #if defined(SQLITE_WIN32_HAS_ANSI)
   { "OutputDebugStringA",      (SYSCALL)OutputDebugStringA,      0 },
@@ -33007,7 +30982,7 @@ static struct win_syscall {
   { "OutputDebugStringA",      (SYSCALL)0,                       0 },
 #endif
 
-#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[69].pCurrent)
+#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[70].pCurrent)
 
 #if defined(SQLITE_WIN32_HAS_WIDE)
   { "OutputDebugStringW",      (SYSCALL)OutputDebugStringW,      0 },
@@ -33015,20 +30990,20 @@ static struct win_syscall {
   { "OutputDebugStringW",      (SYSCALL)0,                       0 },
 #endif
 
-#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[70].pCurrent)
+#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[71].pCurrent)
 
   { "GetProcessHeap",          (SYSCALL)GetProcessHeap,          0 },
 
-#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[71].pCurrent)
+#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[72].pCurrent)
 
-#if SQLITE_OS_WINRT
+#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
   { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
 #else
   { "CreateFileMappingFromApp", (SYSCALL)0,                      0 },
 #endif
 
 #define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
-        LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[72].pCurrent)
+        LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[73].pCurrent)
 
 }; /* End of the overrideable system calls */
 
@@ -33186,6 +31161,8 @@ SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){
 */
 #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 ){
@@ -33196,7 +31173,7 @@ SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){
     }
     return sqlite3_os_type==2;
   }
-#endif /* SQLITE_OS_WINCE */
+#endif
 
 #ifdef SQLITE_WIN32_MALLOC
 /*
@@ -33406,7 +31383,7 @@ static LPWSTR utf8ToUnicode(const char *zFilename){
   if( nChar==0 ){
     return 0;
   }
-  zWideFilename = sqlite3_malloc( nChar*sizeof(zWideFilename[0]) );
+  zWideFilename = sqlite3MallocZero( nChar*sizeof(zWideFilename[0]) );
   if( zWideFilename==0 ){
     return 0;
   }
@@ -33431,7 +31408,7 @@ static char *unicodeToUtf8(LPCWSTR zWideFilename){
   if( nByte == 0 ){
     return 0;
   }
-  zFilename = sqlite3_malloc( nByte );
+  zFilename = sqlite3MallocZero( nByte );
   if( zFilename==0 ){
     return 0;
   }
@@ -33461,7 +31438,7 @@ static LPWSTR mbcsToUnicode(const char *zFilename){
   if( nByte==0 ){
     return 0;
   }
-  zMbcsFilename = sqlite3_malloc( nByte*sizeof(zMbcsFilename[0]) );
+  zMbcsFilename = sqlite3MallocZero( nByte*sizeof(zMbcsFilename[0]) );
   if( zMbcsFilename==0 ){
     return 0;
   }
@@ -33490,7 +31467,7 @@ static char *unicodeToMbcs(LPCWSTR zWideFilename){
   if( nByte == 0 ){
     return 0;
   }
-  zFilename = sqlite3_malloc( nByte );
+  zFilename = sqlite3MallocZero( nByte );
   if( zFilename==0 ){
     return 0;
   }
@@ -33537,6 +31514,42 @@ SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){
   return zFilenameMbcs;
 }
 
+/*
+** 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;
+#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
@@ -33631,7 +31644,7 @@ static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
 ** 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 the associated file-system path, if any.
+** failed and the associated file-system path, if any.
 */
 #define winLogError(a,b,c,d)   winLogErrorAtLine(a,b,c,d,__LINE__)
 static int winLogErrorAtLine(
@@ -34153,7 +32166,9 @@ static int winClose(sqlite3_file *id){
   winFile *pFile = (winFile*)id;
 
   assert( id!=0 );
+#ifndef SQLITE_OMIT_WAL
   assert( pFile->pShm==0 );
+#endif
   OSTRACE(("CLOSE %d\n", pFile->h));
   do{
     rc = osCloseHandle(pFile->h);
@@ -34284,7 +32299,8 @@ static int winWrite(
         if( retryIoerr(&nRetry, &lastErrno) ) continue;
         break;
       }
-      if( nWrite<=0 ){
+      assert( nWrite==0 || nWrite<=(DWORD)nRem );
+      if( nWrite==0 || nWrite>(DWORD)nRem ){
         lastErrno = osGetLastError();
         break;
       }
@@ -34782,6 +32798,9 @@ static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){
   }
 }
 
+/* Forward declaration */
+static int getTempname(int nBuf, char *zBuf);
+
 /*
 ** Control and query of the open file handle.
 */
@@ -34842,6 +32861,14 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
       }
       return SQLITE_OK;
     }
+    case SQLITE_FCNTL_TEMPFILENAME: {
+      char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
+      if( zTFile ){
+        getTempname(pFile->pVfs->mxPathname, zTFile);
+        *(char**)pArg = zTFile;
+      }
+      return SQLITE_OK;
+    }
   }
   return SQLITE_NOTFOUND;
 }
@@ -35099,16 +33126,14 @@ static int winOpenSharedMemory(winFile *pDbFd){
   /* Allocate space for the new sqlite3_shm object.  Also speculatively
   ** allocate space for a new winShmNode and filename.
   */
-  p = sqlite3_malloc( sizeof(*p) );
+  p = sqlite3MallocZero( sizeof(*p) );
   if( p==0 ) return SQLITE_IOERR_NOMEM;
-  memset(p, 0, sizeof(*p));
   nName = sqlite3Strlen30(pDbFd->zPath);
-  pNew = sqlite3_malloc( sizeof(*pShmNode) + nName + 17 );
+  pNew = sqlite3MallocZero( sizeof(*pShmNode) + nName + 17 );
   if( pNew==0 ){
     sqlite3_free(p);
     return SQLITE_IOERR_NOMEM;
   }
-  memset(pNew, 0, sizeof(*pNew) + nName + 17);
   pNew->zFilename = (char*)&pNew[1];
   sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
   sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename); 
@@ -35445,17 +33470,21 @@ static int winShmMap(
     pShmNode->aRegion = apNew;
 
     while( pShmNode->nRegion<=iRegion ){
-      HANDLE hMap;                /* file-mapping handle */
+      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
       );
-#else
+#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 pid-%d create region=%d nbyte=%d %s\n",
                (int)osGetCurrentProcessId(), pShmNode->nRegion, nByte,
@@ -35755,6 +33784,13 @@ static int winOpen(
   assert( id!=0 );
   UNUSED_PARAMETER(pVfs);
 
+#if SQLITE_OS_WINRT
+  if( !sqlite3_temp_directory ){
+    sqlite3_log(SQLITE_ERROR,
+        "sqlite3_temp_directory variable should be set for WinRT");
+  }
+#endif
+
   pFile->h = INVALID_HANDLE_VALUE;
 
   /* If the second argument to this function is NULL, generate a 
@@ -35903,7 +33939,9 @@ static int winOpen(
   pFile->h = h;
   pFile->lastErrno = NO_ERROR;
   pFile->pVfs = pVfs;
+#ifndef SQLITE_OMIT_WAL
   pFile->pShm = 0;
+#endif
   pFile->zPath = zName;
   if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
     pFile->ctrlFlags |= WINFILE_PSOW;
@@ -35968,14 +34006,24 @@ static int winDelete(
                                   &sAttrData) ){
         attr = sAttrData.dwFileAttributes;
       }else{
-        rc = SQLITE_OK; /* Already gone? */
+        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
       if ( attr==INVALID_FILE_ATTRIBUTES ){
-        rc = SQLITE_OK; /* Already gone? */
+        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 ){
@@ -35997,7 +34045,12 @@ static int winDelete(
     do {
       attr = osGetFileAttributesA(zConverted);
       if ( attr==INVALID_FILE_ATTRIBUTES ){
-        rc = SQLITE_OK; /* Already gone? */
+        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 ){
@@ -36015,7 +34068,7 @@ static int winDelete(
     } while(1);
   }
 #endif
-  if( rc ){
+  if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){
     rc = winLogError(SQLITE_IOERR_DELETE, lastErrno,
              "winDelete", zFilename);
   }else{
@@ -36066,7 +34119,7 @@ static int winAccess(
       }
     }else{
       logIoerr(cnt);
-      if( lastErrno!=ERROR_FILE_NOT_FOUND ){
+      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;
@@ -36195,7 +34248,7 @@ static int winFullPathname(
 #endif
 
 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)
-  int nByte;
+  DWORD nByte;
   void *zConverted;
   char *zOut;
 
@@ -36229,13 +34282,27 @@ static int winFullPathname(
   }
   if( isNT() ){
     LPWSTR zTemp;
-    nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0) + 3;
-    zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) );
+    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;
     }
-    osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
+    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);
@@ -36243,13 +34310,27 @@ static int winFullPathname(
 #ifdef SQLITE_WIN32_HAS_ANSI
   else{
     char *zTemp;
-    nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0) + 3;
-    zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) );
+    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;
     }
-    osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
+    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);
@@ -36507,7 +34588,7 @@ SQLITE_API int sqlite3_os_init(void){
 
   /* Double-check that the aSyscall[] array has been constructed
   ** correctly.  See ticket [bb3a86e890c8e96ab] */
-  assert( ArraySize(aSyscall)==73 );
+  assert( ArraySize(aSyscall)==74 );
 
 #ifndef SQLITE_OMIT_WAL
   /* get memory map allocation granularity */
@@ -36526,7 +34607,7 @@ SQLITE_API int sqlite3_os_init(void){
 
 SQLITE_API int sqlite3_os_end(void){ 
 #if SQLITE_OS_WINRT
-  if( sleepObj != NULL ){
+  if( sleepObj!=NULL ){
     osCloseHandle(sleepObj);
     sleepObj = NULL;
   }
@@ -36879,10 +34960,9 @@ SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){
   /* Allocate the Bitvec to be tested and a linear array of
   ** bits to act as the reference */
   pBitvec = sqlite3BitvecCreate( sz );
-  pV = sqlite3_malloc( (sz+7)/8 + 1 );
+  pV = sqlite3MallocZero( (sz+7)/8 + 1 );
   pTmpSpace = sqlite3_malloc(BITVEC_SZ);
   if( pBitvec==0 || pV==0 || pTmpSpace==0  ) goto bitvec_end;
-  memset(pV, 0, (sz+7)/8 + 1);
 
   /* NULL pBitvec tests */
   sqlite3BitvecSet(0, 1);
@@ -37966,11 +36046,10 @@ static int pcache1ResizeHash(PCache1 *p){
 
   pcache1LeaveMutex(p->pGroup);
   if( p->nHash ){ sqlite3BeginBenignMalloc(); }
-  apNew = (PgHdr1 **)sqlite3_malloc(sizeof(PgHdr1 *)*nNew);
+  apNew = (PgHdr1 **)sqlite3MallocZero(sizeof(PgHdr1 *)*nNew);
   if( p->nHash ){ sqlite3EndBenignMalloc(); }
   pcache1EnterMutex(p->pGroup);
   if( apNew ){
-    memset(apNew, 0, sizeof(PgHdr1 *)*nNew);
     for(i=0; i<p->nHash; i++){
       PgHdr1 *pPage;
       PgHdr1 *pNext = p->apHash[i];
@@ -38154,9 +36233,8 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
   assert( szExtra < 300 );
 
   sz = sizeof(PCache1) + sizeof(PGroup)*separateCache;
-  pCache = (PCache1 *)sqlite3_malloc(sz);
+  pCache = (PCache1 *)sqlite3MallocZero(sz);
   if( pCache ){
-    memset(pCache, 0, sz);
     if( separateCache ){
       pGroup = (PGroup*)&pCache[1];
       pGroup->mxPinned = 10;
@@ -39034,7 +37112,7 @@ SQLITE_PRIVATE int sqlite3RowSetNext(RowSet *p, i64 *pRowid){
 }
 
 /*
-** Check to see if element iRowid was inserted into the the rowset as
+** Check to see if element iRowid was inserted into the rowset as
 ** part of any insert batch prior to iBatch.  Return 1 or 0.
 **
 ** If this is the first test of a new batch and if there exist entires
@@ -39318,7 +37396,7 @@ SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal);
 ** 
 ** Definition: Two databases (or the same database at two points it time)
 ** are said to be "logically equivalent" if they give the same answer to
-** all queries.  Note in particular the the content of freelist leaf
+** all queries.  Note in particular the content of freelist leaf
 ** pages can be changed arbitarily without effecting the logical equivalence
 ** of the database.
 ** 
@@ -41184,12 +39262,13 @@ static int pager_end_transaction(Pager *pPager, int hasMaster){
       ** 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( !pPager->tempFile ){
+      if( bDelete ){
         rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
       }
     }
@@ -41752,6 +39831,21 @@ static int pager_truncate(Pager *pPager, Pgno nPage){
   return rc;
 }
 
+/*
+** 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 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;
+}
+
 /*
 ** Set the value of the Pager.sectorSize variable for the given
 ** pager based on the value returned by the xSectorSize method
@@ -41787,14 +39881,7 @@ static void setSectorSize(Pager *pPager){
     ** call will segfault. */
     pPager->sectorSize = 512;
   }else{
-    pPager->sectorSize = sqlite3OsSectorSize(pPager->fd);
-    if( pPager->sectorSize<32 ){
-      pPager->sectorSize = 512;
-    }
-    if( pPager->sectorSize>MAX_SECTOR_SIZE ){
-      assert( MAX_SECTOR_SIZE>=512 );
-      pPager->sectorSize = MAX_SECTOR_SIZE;
-    }
+    pPager->sectorSize = sqlite3SectorSize(pPager->fd);
   }
 }
 
@@ -42394,6 +40481,7 @@ static int pagerOpenWalIfPresent(Pager *pPager){
     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(
@@ -42711,9 +40799,16 @@ 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);
+  }
 }
 
 /*
@@ -43092,7 +41187,7 @@ SQLITE_PRIVATE void sqlite3PagerRef(DbPage *pPg){
 **
 ** 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 the file-system, as follows:
+** device characteristics of the file-system, as follows:
 **
 **   * If the journal file is an in-memory journal file, no action need
 **     be taken.
@@ -43691,7 +41786,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
     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+1);
+    memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+2);
     sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal);
 #ifndef SQLITE_OMIT_WAL
     pPager->zWal = &pPager->zJournal[nPathname+8+1];
@@ -44893,7 +42988,7 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
 # define DIRECT_MODE isDirectMode
 #endif
 
-  if( !pPager->changeCountDone && pPager->dbSize>0 ){
+  if( !pPager->changeCountDone && ALWAYS(pPager->dbSize>0) ){
     PgHdr *pPgHdr;                /* Reference to page 1 */
 
     assert( !pPager->tempFile && isOpen(pPager->fd) );
@@ -45113,7 +43208,7 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
   
       /* If this transaction has made the database smaller, then all pages
       ** being discarded by the truncation must be written to the journal
-      ** file. This can only happen in auto-vacuum mode.
+      ** file.
       **
       ** Before reading the pages with page numbers larger than the 
       ** current value of Pager.dbSize, set dbSize back to the value
@@ -45121,7 +43216,6 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
       ** calls to sqlite3PagerGet() return zeroed pages instead of 
       ** reading data from the database file.
       */
-  #ifndef SQLITE_OMIT_AUTOVACUUM
       if( pPager->dbSize<pPager->dbOrigSize 
        && pPager->journalMode!=PAGER_JOURNALMODE_OFF
       ){
@@ -45141,7 +43235,6 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
         }
         pPager->dbSize = dbSize;
       } 
-  #endif
   
       /* Write the master journal name into the journal file. If a master 
       ** journal file name has already been written to the journal file, 
@@ -46144,6 +44237,8 @@ SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager){
   return rc;
 }
 
+#endif /* !SQLITE_OMIT_WAL */
+
 #ifdef SQLITE_ENABLE_ZIPVFS
 /*
 ** A read-lock must be held on the pager when this function is called. If
@@ -46173,8 +44268,6 @@ SQLITE_PRIVATE void *sqlite3PagerCodec(PgHdr *pPg){
 }
 #endif /* SQLITE_HAS_CODEC */
 
-#endif /* !SQLITE_OMIT_WAL */
-
 #endif /* SQLITE_OMIT_DISKIO */
 
 /************** End of pager.c ***********************************************/
@@ -46323,14 +44416,15 @@ SQLITE_PRIVATE void *sqlite3PagerCodec(PgHdr *pPg){
 ** byte order of the host computer.
 **
 ** The purpose of the wal-index is to answer this question quickly:  Given
-** a page number P, return the index of the last frame for page P in the WAL,
-** or return NULL if there are no frames for page P in the WAL.
+** 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 the mxFrame field.  
+** in the mxFrame field.
 **
 ** Each index block except for the first contains information on 
 ** HASHTABLE_NPAGE frames. The first index block contains information on
@@ -47378,6 +45472,7 @@ finished:
     pInfo->nBackfill = 0;
     pInfo->aReadMark[0] = 0;
     for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
+    if( pWal->hdr.mxFrame ) pInfo->aReadMark[1] = pWal->hdr.mxFrame;
 
     /* If more than one frame was recovered from the log file, report an
     ** event via sqlite3_log(). This is to help with identifying performance
@@ -47878,7 +45973,7 @@ static int walCheckpoint(
       assert( y<=pWal->hdr.mxFrame );
       rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
       if( rc==SQLITE_OK ){
-        pInfo->aReadMark[i] = READMARK_NOT_USED;
+        pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
         walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
       }else if( rc==SQLITE_BUSY ){
         mxSafeFrame = y;
@@ -48696,7 +46791,7 @@ SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *p
       assert( walFramePgno(pWal, iFrame)!=1 );
       rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame));
     }
-    walCleanupHash(pWal);
+    if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal);
   }
   assert( rc==SQLITE_OK );
   return rc;
@@ -48791,7 +46886,8 @@ static int walRestartLog(Wal *pWal){
         aSalt[1] = salt1;
         walIndexWriteHdr(pWal);
         pInfo->nBackfill = 0;
-        for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
+        pInfo->aReadMark[1] = 0;
+        for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
         assert( pInfo->aReadMark[0]==0 );
         walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
       }else if( rc!=SQLITE_BUSY ){
@@ -49005,7 +47101,7 @@ SQLITE_PRIVATE int sqlite3WalFrames(
   */
   if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){
     if( pWal->padToSectorBoundary ){
-      int sectorSize = sqlite3OsSectorSize(pWal->pWalFd);
+      int sectorSize = sqlite3SectorSize(pWal->pWalFd);
       w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize;
       while( iOffset<w.iSyncPoint ){
         rc = walWriteOneFrame(&w, pLast, nTruncate, iOffset);
@@ -49794,6 +47890,7 @@ struct BtCursor {
 #ifndef SQLITE_OMIT_INCRBLOB
   u8 isIncrblobHandle;      /* True if this cursor is an incr. io handle */
 #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] */
   MemPage *apPage[BTCURSOR_MAX_DEPTH];  /* Pages from root to current page */
@@ -51678,7 +49775,7 @@ static int btreeInitPage(MemPage *pPage){
       size = get2byte(&data[pc+2]);
       if( (next>0 && next<=pc+size+3) || pc+size>usableSize ){
         /* Free blocks must be in ascending order. And the last byte of
-       ** the free-block must lie on the database page.  */
+        ** the free-block must lie on the database page.  */
         return SQLITE_CORRUPT_BKPT; 
       }
       nFree = nFree + size;
@@ -52417,6 +50514,24 @@ SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree *p){
   return p->pBt->pageSize;
 }
 
+#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_DEBUG)
+/*
+** This function is similar to sqlite3BtreeGetReserve(), except that it
+** may only be called if it is guaranteed that the b-tree mutex is already
+** held.
+**
+** This is useful in one special case in the backup API code where it is
+** known that the shared b-tree mutex is held, but the mutex on the 
+** database handle that owns *p is not. In this case if sqlite3BtreeEnter()
+** were to be called, it might collide with some other operation on the
+** database handle that owns *p, causing undefined behaviour.
+*/
+SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p){
+  assert( sqlite3_mutex_held(p->pBt->mutex) );
+  return p->pBt->pageSize - p->pBt->usableSize;
+}
+#endif /* SQLITE_HAS_CODEC || SQLITE_DEBUG */
+
 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM)
 /*
 ** Return the number of bytes of space at the end of every page that
@@ -52730,6 +50845,20 @@ static int newDatabase(BtShared *pBt){
   return SQLITE_OK;
 }
 
+/*
+** Initialize the first page of the database file (creating a database
+** consisting of a single page and no schema objects). Return SQLITE_OK
+** if successful, or an SQLite error code otherwise.
+*/
+SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p){
+  int rc;
+  sqlite3BtreeEnter(p);
+  p->pBt->nPage = 0;
+  rc = newDatabase(p->pBt);
+  sqlite3BtreeLeave(p);
+  return rc;
+}
+
 /*
 ** Attempt to start a new transaction. A write-transaction
 ** is started if the second argument is nonzero, otherwise a read-
@@ -52852,7 +50981,7 @@ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
       pBt->nTransaction++;
 #ifndef SQLITE_OMIT_SHARED_CACHE
       if( p->sharable ){
-       assert( p->lock.pBtree==p && p->lock.iTable==1 );
+        assert( p->lock.pBtree==p && p->lock.iTable==1 );
         p->lock.eLock = READ_LOCK;
         p->lock.pNext = pBt->pLock;
         pBt->pLock = &p->lock;
@@ -55473,7 +53602,7 @@ static int clearCell(MemPage *pPage, unsigned char *pCell){
     return SQLITE_OK;  /* No overflow pages. Return without doing anything */
   }
   if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){
-    return SQLITE_CORRUPT;  /* Cell extends past end of page */
+    return SQLITE_CORRUPT_BKPT;  /* Cell extends past end of page */
   }
   ovflPgno = get4byte(&pCell[info.iOverflow]);
   assert( pBt->usableSize > 4 );
@@ -55929,7 +54058,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
   assert( pPage->nOverflow==1 );
 
   /* This error condition is now caught prior to reaching this function */
-  if( pPage->nCell<=0 ) return SQLITE_CORRUPT_BKPT;
+  if( pPage->nCell==0 ) return SQLITE_CORRUPT_BKPT;
 
   /* Allocate a new page. This page will become the right-sibling of 
   ** pPage. Make the parent page writable, so that the new divider cell
@@ -56139,11 +54268,15 @@ static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){
 ** If aOvflSpace is set to a null pointer, this function returns 
 ** SQLITE_NOMEM.
 */
+#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
+#pragma optimize("", off)
+#endif
 static int balance_nonroot(
   MemPage *pParent,               /* Parent page of siblings being balanced */
   int iParentIdx,                 /* Index of "the page" in pParent */
   u8 *aOvflSpace,                 /* page-size bytes of space for parent ovfl */
-  int isRoot                      /* True if pParent is a root-page */
+  int isRoot,                     /* True if pParent is a root-page */
+  int bBulk                       /* True if this call is part of a bulk load */
 ){
   BtShared *pBt;               /* The whole database */
   int nCell = 0;               /* Number of cells in apCell[] */
@@ -56207,18 +54340,19 @@ static int balance_nonroot(
   i = pParent->nOverflow + pParent->nCell;
   if( i<2 ){
     nxDiv = 0;
-    nOld = i+1;
   }else{
-    nOld = 3;
+    assert( bBulk==0 || bBulk==1 );
     if( iParentIdx==0 ){                 
       nxDiv = 0;
     }else if( iParentIdx==i ){
-      nxDiv = i-2;
+      nxDiv = i-2+bBulk;
     }else{
+      assert( bBulk==0 );
       nxDiv = iParentIdx-1;
     }
-    i = 2;
+    i = 2-bBulk;
   }
+  nOld = i+1;
   if( (i+nxDiv-pParent->nOverflow)==pParent->nCell ){
     pRight = &pParent->aData[pParent->hdrOffset+8];
   }else{
@@ -56298,7 +54432,7 @@ static int balance_nonroot(
   /*
   ** Load pointers to all cells on sibling pages and the divider cells
   ** into the local apCell[] array.  Make copies of the divider cells
-  ** into space obtained from aSpace1[] and remove the the divider Cells
+  ** into space obtained from aSpace1[] and remove the divider cells
   ** from pParent.
   **
   ** If the siblings are on leaf pages, then the child pointers of the
@@ -56427,7 +54561,9 @@ static int balance_nonroot(
     d = r + 1 - leafData;
     assert( d<nMaxCells );
     assert( r<nMaxCells );
-    while( szRight==0 || szRight+szCell[d]+2<=szLeft-(szCell[r]+2) ){
+    while( szRight==0 
+       || (!bBulk && szRight+szCell[d]+2<=szLeft-(szCell[r]+2)) 
+    ){
       szRight += szCell[d] + 2;
       szLeft -= szCell[r] + 2;
       cntNew[i-1]--;
@@ -56474,7 +54610,7 @@ static int balance_nonroot(
       if( rc ) goto balance_cleanup;
     }else{
       assert( i>0 );
-      rc = allocateBtreePage(pBt, &pNew, &pgno, pgno, 0);
+      rc = allocateBtreePage(pBt, &pNew, &pgno, (bBulk ? 1 : pgno), 0);
       if( rc ) goto balance_cleanup;
       apNew[i] = pNew;
       nNew++;
@@ -56686,6 +54822,7 @@ static int balance_nonroot(
         ** sibling page j. If the siblings are not leaf pages of an
         ** intkey b-tree, then cell i was a divider cell. */
         assert( j+1 < ArraySize(apCopy) );
+        assert( j+1 < nOld );
         pOld = apCopy[++j];
         iNextOld = i + !leafData + pOld->nCell + pOld->nOverflow;
         if( pOld->nOverflow ){
@@ -56764,6 +54901,9 @@ balance_cleanup:
 
   return rc;
 }
+#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
+#pragma optimize("", on)
+#endif
 
 
 /*
@@ -56924,7 +55064,7 @@ static int balance(BtCursor *pCur){
           ** pSpace buffer passed to the latter call to balance_nonroot().
           */
           u8 *pSpace = sqlite3PageMalloc(pCur->pBt->pageSize);
-          rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1);
+          rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1, pCur->hints);
           if( pFree ){
             /* If pFree is not NULL, it points to the pSpace buffer used 
             ** by a previous call to balance_nonroot(). Its contents are
@@ -58512,6 +56652,15 @@ SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){
   return rc;
 }
 
+/*
+** set the mask of hint flags for cursor pCsr. Currently the only valid
+** values are 0 and BTREE_BULKLOAD.
+*/
+SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *pCsr, unsigned int mask){
+  assert( mask==BTREE_BULKLOAD || mask==0 );
+  pCsr->hints = mask;
+}
+
 /************** End of btree.c ***********************************************/
 /************** Begin file backup.c ******************************************/
 /*
@@ -58678,7 +56827,7 @@ SQLITE_API sqlite3_backup *sqlite3_backup_init(
     ** EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a
     ** call to sqlite3_backup_init() and is destroyed by a call to
     ** sqlite3_backup_finish(). */
-    p = (sqlite3_backup *)sqlite3_malloc(sizeof(sqlite3_backup));
+    p = (sqlite3_backup *)sqlite3MallocZero(sizeof(sqlite3_backup));
     if( !p ){
       sqlite3Error(pDestDb, SQLITE_NOMEM, 0);
     }
@@ -58686,7 +56835,6 @@ SQLITE_API sqlite3_backup *sqlite3_backup_init(
 
   /* If the allocation succeeded, populate the new object. */
   if( p ){
-    memset(p, 0, sizeof(sqlite3_backup));
     p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb);
     p->pDest = findBtree(pDestDb, pDestDb, zDestDb);
     p->pDestDb = pDestDb;
@@ -58734,13 +56882,16 @@ static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
   const int nCopy = MIN(nSrcPgsz, nDestPgsz);
   const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
 #ifdef SQLITE_HAS_CODEC
-  int nSrcReserve = sqlite3BtreeGetReserve(p->pSrc);
+  /* Use BtreeGetReserveNoMutex() for the source b-tree, as although it is
+  ** guaranteed that the shared-mutex is held by this thread, handle
+  ** p->pSrc may not actually be the owner.  */
+  int nSrcReserve = sqlite3BtreeGetReserveNoMutex(p->pSrc);
   int nDestReserve = sqlite3BtreeGetReserve(p->pDest);
 #endif
-
   int rc = SQLITE_OK;
   i64 iOff;
 
+  assert( sqlite3BtreeGetReserveNoMutex(p->pSrc)>=0 );
   assert( p->bDestLocked );
   assert( !isFatalError(p->rc) );
   assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) );
@@ -58925,7 +57076,13 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
     ** same schema version.
     */
     if( rc==SQLITE_DONE ){
-      rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1);
+      if( nSrcPage==0 ){
+        rc = sqlite3BtreeNewDb(p->pDest);
+        nSrcPage = 1;
+      }
+      if( rc==SQLITE_OK || rc==SQLITE_DONE ){
+        rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1);
+      }
       if( rc==SQLITE_OK ){
         if( p->pDestDb ){
           sqlite3ResetAllSchemasOfConnection(p->pDestDb);
@@ -58959,6 +57116,7 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
         }else{
           nDestTruncate = nSrcPage * (pgszSrc/pgszDest);
         }
+        assert( nDestTruncate>0 );
         sqlite3PagerTruncateImage(pDestPager, nDestTruncate);
 
         if( pgszSrc<pgszDest ){
@@ -58977,7 +57135,8 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
           i64 iEnd;
 
           assert( pFile );
-          assert( (i64)nDestTruncate*(i64)pgszDest >= iSize || (
+          assert( nDestTruncate==0 
+              || (i64)nDestTruncate*(i64)pgszDest >= iSize || (
                 nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1)
              && iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+pgszDest
           ));
@@ -59057,14 +57216,14 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
 */
 SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
   sqlite3_backup **pp;                 /* Ptr to head of pagers backup list */
-  MUTEX_LOGIC( sqlite3_mutex *mutex; ) /* Mutex to protect source database */
+  sqlite3 *pSrcDb;                     /* Source database connection */
   int rc;                              /* Value to return */
 
   /* Enter the mutexes */
   if( p==0 ) return SQLITE_OK;
-  sqlite3_mutex_enter(p->pSrcDb->mutex);
+  pSrcDb = p->pSrcDb;
+  sqlite3_mutex_enter(pSrcDb->mutex);
   sqlite3BtreeEnter(p->pSrc);
-  MUTEX_LOGIC( mutex = p->pSrcDb->mutex; )
   if( p->pDestDb ){
     sqlite3_mutex_enter(p->pDestDb->mutex);
   }
@@ -59090,7 +57249,7 @@ SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
 
   /* Exit the mutexes and free the backup context structure. */
   if( p->pDestDb ){
-    sqlite3_mutex_leave(p->pDestDb->mutex);
+    sqlite3LeaveMutexAndCloseZombie(p->pDestDb);
   }
   sqlite3BtreeLeave(p->pSrc);
   if( p->pDestDb ){
@@ -59099,7 +57258,7 @@ SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
     ** sqlite3_backup_finish(). */
     sqlite3_free(p);
   }
-  sqlite3_mutex_leave(mutex);
+  sqlite3LeaveMutexAndCloseZombie(pSrcDb);
   return rc;
 }
 
@@ -60447,7 +58606,7 @@ SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(sqlite3 *db){
 SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){
   assert( isPrepareV2==1 || isPrepareV2==0 );
   if( p==0 ) return;
-#ifdef SQLITE_OMIT_TRACE
+#if defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_ENABLE_SQLLOG)
   if( !isPrepareV2 ) return;
 #endif
   assert( p->zSql==0 );
@@ -61117,6 +59276,7 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int
     addr = p->nOp - 1;
   }
   pOp = &p->aOp[addr];
+  assert( pOp->p4type==P4_NOTUSED || pOp->p4type==P4_INT32 );
   freeP4(db, pOp->p4type, pOp->p4.p);
   pOp->p4.p = 0;
   if( n==P4_INT32 ){
@@ -61139,10 +59299,9 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int
       u8 *aSortOrder;
       memcpy((char*)pKeyInfo, zP4, nByte - nField);
       aSortOrder = pKeyInfo->aSortOrder;
-      if( aSortOrder ){
-        pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField];
-        memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
-      }
+      assert( aSortOrder!=0 );
+      pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField];
+      memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
       pOp->p4type = P4_KEYINFO;
     }else{
       p->db->mallocFailed = 1;
@@ -61168,7 +59327,7 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int
 
 #ifndef NDEBUG
 /*
-** Change the comment on the the most recently coded instruction.  Or
+** Change the comment on the most recently coded instruction.  Or
 ** insert a No-op and add the comment to that new instruction.  This
 ** makes the code easier to read during debugging.  None of this happens
 ** in a production build.
@@ -61255,26 +59414,23 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
     case P4_KEYINFO: {
       int i, j;
       KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
+      assert( pKeyInfo->aSortOrder!=0 );
       sqlite3_snprintf(nTemp, zTemp, "keyinfo(%d", pKeyInfo->nField);
       i = sqlite3Strlen30(zTemp);
       for(j=0; j<pKeyInfo->nField; j++){
         CollSeq *pColl = pKeyInfo->aColl[j];
-        if( pColl ){
-          int n = sqlite3Strlen30(pColl->zName);
-          if( i+n>nTemp-6 ){
-            memcpy(&zTemp[i],",...",4);
-            break;
-          }
-          zTemp[i++] = ',';
-          if( pKeyInfo->aSortOrder && pKeyInfo->aSortOrder[j] ){
-            zTemp[i++] = '-';
-          }
-          memcpy(&zTemp[i], pColl->zName,n+1);
-          i += n;
-        }else if( i+4<nTemp-6 ){
-          memcpy(&zTemp[i],",nil",4);
-          i += 4;
+        const char *zColl = pColl ? pColl->zName : "nil";
+        int n = sqlite3Strlen30(zColl);
+        if( i+n>nTemp-6 ){
+          memcpy(&zTemp[i],",...",4);
+          break;
+        }
+        zTemp[i++] = ',';
+        if( pKeyInfo->aSortOrder[j] ){
+          zTemp[i++] = '-';
         }
+        memcpy(&zTemp[i], zColl, n+1);
+        i += n;
       }
       zTemp[i++] = ')';
       zTemp[i] = 0;
@@ -62164,7 +60320,9 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
     if( sqlite3BtreeIsInTrans(pBt) ){
       needXcommit = 1;
       if( i!=1 ) nTrans++;
+      sqlite3BtreeEnter(pBt);
       rc = sqlite3PagerExclusiveLock(sqlite3BtreePager(pBt));
+      sqlite3BtreeLeave(pBt);
     }
   }
   if( rc!=SQLITE_OK ){
@@ -62718,6 +60876,27 @@ SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p){
   return rc;
 }
 
+#ifdef SQLITE_ENABLE_SQLLOG
+/*
+** If an SQLITE_CONFIG_SQLLOG hook is registered and the VM has been run, 
+** invoke it.
+*/
+static void vdbeInvokeSqllog(Vdbe *v){
+  if( sqlite3GlobalConfig.xSqllog && v->rc==SQLITE_OK && v->zSql && v->pc>=0 ){
+    char *zExpanded = sqlite3VdbeExpandSql(v, v->zSql);
+    assert( v->db->init.busy==0 );
+    if( zExpanded ){
+      sqlite3GlobalConfig.xSqllog(
+          sqlite3GlobalConfig.pSqllogArg, v->db, zExpanded, 1
+      );
+      sqlite3DbFree(v->db, zExpanded);
+    }
+  }
+}
+#else
+# define vdbeInvokeSqllog(x)
+#endif
+
 /*
 ** Clean up a VDBE after execution but do not delete the VDBE just yet.
 ** Write any error messages into *pzErrMsg.  Return the result code.
@@ -62745,6 +60924,7 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
   ** instructions yet, leave the main database error information unchanged.
   */
   if( p->pc>=0 ){
+    vdbeInvokeSqllog(p);
     sqlite3VdbeTransferError(p);
     sqlite3DbFree(db, p->zErrMsg);
     p->zErrMsg = 0;
@@ -62826,12 +61006,14 @@ SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){
 }
 
 /*
-** Free all memory associated with the Vdbe passed as the second argument.
+** Free all memory associated with the Vdbe passed as the second argument,
+** except for object itself, which is preserved.
+**
 ** The difference between this function and sqlite3VdbeDelete() is that
 ** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with
-** the database connection.
+** the database connection and frees the object itself.
 */
-SQLITE_PRIVATE void sqlite3VdbeDeleteObject(sqlite3 *db, Vdbe *p){
+SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
   SubProgram *pSub, *pNext;
   int i;
   assert( p->db==0 || p->db==db );
@@ -62849,10 +61031,9 @@ SQLITE_PRIVATE void sqlite3VdbeDeleteObject(sqlite3 *db, Vdbe *p){
   sqlite3DbFree(db, p->zSql);
   sqlite3DbFree(db, p->pFree);
 #if defined(SQLITE_ENABLE_TREE_EXPLAIN)
-  sqlite3DbFree(db, p->zExplain);
+  sqlite3_free(p->zExplain);
   sqlite3DbFree(db, p->pExplain);
 #endif
-  sqlite3DbFree(db, p);
 }
 
 /*
@@ -62863,6 +61044,8 @@ SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){
 
   if( NEVER(p==0) ) return;
   db = p->db;
+  assert( sqlite3_mutex_held(db->mutex) );
+  sqlite3VdbeClearObject(db, p);
   if( p->pPrev ){
     p->pPrev->pNext = p->pNext;
   }else{
@@ -62874,7 +61057,7 @@ SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){
   }
   p->magic = VDBE_MAGIC_DEAD;
   p->db = 0;
-  sqlite3VdbeDeleteObject(db, p);
+  sqlite3DbFree(db, p);
 }
 
 /*
@@ -62976,9 +61159,6 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
 #   define MAX_6BYTE ((((i64)0x00008000)<<32)-1)
     i64 i = pMem->u.i;
     u64 u;
-    if( file_format>=4 && (i&1)==i ){
-      return 8+(u32)i;
-    }
     if( i<0 ){
       if( i<(-MAX_6BYTE) ) return 6;
       /* Previous test prevents:  u = -(-9223372036854775808) */
@@ -62986,7 +61166,9 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
     }else{
       u = i;
     }
-    if( u<=127 ) return 1;
+    if( u<=127 ){
+      return ((i&1)==i && file_format>=4) ? 8+(u32)u : 1;
+    }
     if( u<=32767 ) return 2;
     if( u<=8388607 ) return 3;
     if( u<=2147483647 ) return 4;
@@ -63271,6 +61453,7 @@ SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(
   }
 
   p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))];
+  assert( pKeyInfo->aSortOrder!=0 );
   p->pKeyInfo = pKeyInfo;
   p->nField = pKeyInfo->nField + 1;
   return p;
@@ -63364,6 +61547,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
   idx1 = getVarint32(aKey1, szHdr1);
   d1 = szHdr1;
   nField = pKeyInfo->nField;
+  assert( pKeyInfo->aSortOrder!=0 );
   while( idx1<szHdr1 && i<pPKey2->nField ){
     u32 serial_type1;
 
@@ -63383,7 +61567,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
       assert( mem1.zMalloc==0 );  /* See comment below */
 
       /* Invert the result if we are using DESC sort order. */
-      if( pKeyInfo->aSortOrder && i<nField && pKeyInfo->aSortOrder[i] ){
+      if( i<nField && pKeyInfo->aSortOrder[i] ){
         rc = -rc;
       }
     
@@ -63702,17 +61886,11 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){
   }else{
     Vdbe *v = (Vdbe*)pStmt;
     sqlite3 *db = v->db;
-#if SQLITE_THREADSAFE
-    sqlite3_mutex *mutex;
-#endif
     if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT;
-#if SQLITE_THREADSAFE
-    mutex = v->db->mutex;
-#endif
-    sqlite3_mutex_enter(mutex);
+    sqlite3_mutex_enter(db->mutex);
     rc = sqlite3VdbeFinalize(v);
     rc = sqlite3ApiExit(db, rc);
-    sqlite3_mutex_leave(mutex);
+    sqlite3LeaveMutexAndCloseZombie(db);
   }
   return rc;
 }
@@ -64115,10 +62293,12 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
   }
   db = v->db;
   sqlite3_mutex_enter(db->mutex);
+  v->doingRerun = 0;
   while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
          && cnt++ < SQLITE_MAX_SCHEMA_RETRY
          && (rc2 = rc = sqlite3Reprepare(v))==SQLITE_OK ){
     sqlite3_reset(pStmt);
+    v->doingRerun = 1;
     assert( v->expired==0 );
   }
   if( rc2!=SQLITE_OK && ALWAYS(v->isPrepareV2) && ALWAYS(db->pErr) ){
@@ -65115,9 +63295,8 @@ SQLITE_PRIVATE void sqlite3ExplainBegin(Vdbe *pVdbe){
   if( pVdbe ){
     Explain *p;
     sqlite3BeginBenignMalloc();
-    p = sqlite3_malloc( sizeof(Explain) );
+    p = (Explain *)sqlite3MallocZero( sizeof(Explain) );
     if( p ){
-      memset(p, 0, sizeof(*p));
       p->pVdbe = pVdbe;
       sqlite3_free(pVdbe->pExplain);
       pVdbe->pExplain = p;
@@ -65641,7 +63820,9 @@ SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){
 ** Print the value of a register for tracing purposes:
 */
 static void memTracePrint(FILE *out, Mem *p){
-  if( p->flags & MEM_Null ){
+  if( p->flags & MEM_Invalid ){
+    fprintf(out, " undefined");
+  }else if( p->flags & MEM_Null ){
     fprintf(out, " NULL");
   }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
     fprintf(out, " si:%lld", p->u.i);
@@ -65892,6 +64073,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
     } aa;
     struct OP_Null_stack_vars {
       int cnt;
+      u16 nullFlag;
     } ab;
     struct OP_Variable_stack_vars {
       Mem *pVar;       /* Value being transferred */
@@ -65902,39 +64084,43 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
       int p1;          /* Register to copy from */
       int p2;          /* Register to copy to */
     } ad;
+    struct OP_Copy_stack_vars {
+      int n;
+    } ae;
     struct OP_ResultRow_stack_vars {
       Mem *pMem;
       int i;
-    } ae;
+    } af;
     struct OP_Concat_stack_vars {
       i64 nByte;
-    } af;
+    } ag;
     struct OP_Remainder_stack_vars {
+      char bIntint;   /* Started out as two integer operands */
       int flags;      /* Combined MEM_* flags from both inputs */
       i64 iA;         /* Integer value of left operand */
       i64 iB;         /* Integer value of right operand */
       double rA;      /* Real value of left operand */
       double rB;      /* Real value of right operand */
-    } ag;
+    } ah;
     struct OP_Function_stack_vars {
       int i;
       Mem *pArg;
       sqlite3_context ctx;
       sqlite3_value **apVal;
       int n;
-    } ah;
+    } ai;
     struct OP_ShiftRight_stack_vars {
       i64 iA;
       u64 uA;
       i64 iB;
       u8 op;
-    } ai;
+    } aj;
     struct OP_Ge_stack_vars {
       int res;            /* Result of the comparison of pIn1 against pIn3 */
       char affinity;      /* Affinity to use for comparison */
       u16 flags1;         /* Copy of initial value of pIn1->flags */
       u16 flags3;         /* Copy of initial value of pIn3->flags */
-    } aj;
+    } ak;
     struct OP_Compare_stack_vars {
       int n;
       int i;
@@ -65944,14 +64130,14 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
       int idx;
       CollSeq *pColl;    /* Collating sequence to use on this term */
       int bRev;          /* True for DESCENDING sort order */
-    } ak;
+    } al;
     struct OP_Or_stack_vars {
       int v1;    /* Left operand:  0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
       int v2;    /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
-    } al;
+    } am;
     struct OP_IfNot_stack_vars {
       int c;
-    } am;
+    } an;
     struct OP_Column_stack_vars {
       u32 payloadSize;   /* Number of bytes in the record */
       i64 payloadSize64; /* Number of bytes in the record */
@@ -65976,11 +64162,11 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
       int avail;         /* Number of bytes of available data */
       u32 t;             /* A type code from the record header */
       Mem *pReg;         /* PseudoTable input register */
-    } an;
+    } ao;
     struct OP_Affinity_stack_vars {
       const char *zAffinity;   /* The affinity to be applied */
       char cAff;               /* A single character of affinity */
-    } ao;
+    } ap;
     struct OP_MakeRecord_stack_vars {
       u8 *zNewRecord;        /* A buffer to hold the data for the new record */
       Mem *pRec;             /* The new record */
@@ -65997,11 +64183,11 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
       int file_format;       /* File format to use for encoding */
       int i;                 /* Space used in zNewRecord[] */
       int len;               /* Length of a field */
-    } ap;
+    } aq;
     struct OP_Count_stack_vars {
       i64 nEntry;
       BtCursor *pCrsr;
-    } aq;
+    } ar;
     struct OP_Savepoint_stack_vars {
       int p1;                         /* Value of P1 operand */
       char *zName;                    /* Name of savepoint */
@@ -66011,28 +64197,28 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
       Savepoint *pTmp;
       int iSavepoint;
       int ii;
-    } ar;
+    } as;
     struct OP_AutoCommit_stack_vars {
       int desiredAutoCommit;
       int iRollback;
       int turnOnAC;
-    } as;
+    } at;
     struct OP_Transaction_stack_vars {
       Btree *pBt;
-    } at;
+    } au;
     struct OP_ReadCookie_stack_vars {
       int iMeta;
       int iDb;
       int iCookie;
-    } au;
+    } av;
     struct OP_SetCookie_stack_vars {
       Db *pDb;
-    } av;
+    } aw;
     struct OP_VerifyCookie_stack_vars {
       int iMeta;
       int iGen;
       Btree *pBt;
-    } aw;
+    } ax;
     struct OP_OpenWrite_stack_vars {
       int nField;
       KeyInfo *pKeyInfo;
@@ -66042,16 +64228,16 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
       Btree *pX;
       VdbeCursor *pCur;
       Db *pDb;
-    } ax;
+    } ay;
     struct OP_OpenEphemeral_stack_vars {
       VdbeCursor *pCx;
-    } ay;
+    } az;
     struct OP_SorterOpen_stack_vars {
       VdbeCursor *pCx;
-    } az;
+    } ba;
     struct OP_OpenPseudo_stack_vars {
       VdbeCursor *pCx;
-    } ba;
+    } bb;
     struct OP_SeekGt_stack_vars {
       int res;
       int oc;
@@ -66059,10 +64245,10 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
       UnpackedRecord r;
       int nField;
       i64 iKey;      /* The rowid we are to seek to */
-    } bb;
+    } bc;
     struct OP_Seek_stack_vars {
       VdbeCursor *pC;
-    } bc;
+    } bd;
     struct OP_Found_stack_vars {
       int alreadyExists;
       VdbeCursor *pC;
@@ -66071,7 +64257,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
       UnpackedRecord *pIdxKey;
       UnpackedRecord r;
       char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7];
-    } bd;
+    } be;
     struct OP_IsUnique_stack_vars {
       u16 ii;
       VdbeCursor *pCx;
@@ -66080,13 +64266,13 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
       Mem *aMx;
       UnpackedRecord r;                  /* B-Tree index search key */
       i64 R;                             /* Rowid stored in register P3 */
-    } be;
+    } bf;
     struct OP_NotExists_stack_vars {
       VdbeCursor *pC;
       BtCursor *pCrsr;
       int res;
       u64 iKey;
-    } bf;
+    } bg;
     struct OP_NewRowid_stack_vars {
       i64 v;                 /* The new rowid */
       VdbeCursor *pC;        /* Cursor of table to get the new rowid */
@@ -66094,7 +64280,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
       int cnt;               /* Counter to limit the number of searches */
       Mem *pMem;             /* Register holding largest rowid for AUTOINCREMENT */
       VdbeFrame *pFrame;     /* Root frame of VDBE */
-    } bg;
+    } bh;
     struct OP_InsertInt_stack_vars {
       Mem *pData;       /* MEM cell holding data for the record to be inserted */
       Mem *pKey;        /* MEM cell holding key  for the record */
@@ -66105,89 +64291,89 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
       const char *zDb;  /* database name - used by the update hook */
       const char *zTbl; /* Table name - used by the opdate hook */
       int op;           /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */
-    } bh;
+    } bi;
     struct OP_Delete_stack_vars {
       i64 iKey;
       VdbeCursor *pC;
-    } bi;
+    } bj;
     struct OP_SorterCompare_stack_vars {
       VdbeCursor *pC;
       int res;
-    } bj;
+    } bk;
     struct OP_SorterData_stack_vars {
       VdbeCursor *pC;
-    } bk;
+    } bl;
     struct OP_RowData_stack_vars {
       VdbeCursor *pC;
       BtCursor *pCrsr;
       u32 n;
       i64 n64;
-    } bl;
+    } bm;
     struct OP_Rowid_stack_vars {
       VdbeCursor *pC;
       i64 v;
       sqlite3_vtab *pVtab;
       const sqlite3_module *pModule;
-    } bm;
+    } bn;
     struct OP_NullRow_stack_vars {
       VdbeCursor *pC;
-    } bn;
+    } bo;
     struct OP_Last_stack_vars {
       VdbeCursor *pC;
       BtCursor *pCrsr;
       int res;
-    } bo;
+    } bp;
     struct OP_Rewind_stack_vars {
       VdbeCursor *pC;
       BtCursor *pCrsr;
       int res;
-    } bp;
+    } bq;
     struct OP_Next_stack_vars {
       VdbeCursor *pC;
       int res;
-    } bq;
+    } br;
     struct OP_IdxInsert_stack_vars {
       VdbeCursor *pC;
       BtCursor *pCrsr;
       int nKey;
       const char *zKey;
-    } br;
+    } bs;
     struct OP_IdxDelete_stack_vars {
       VdbeCursor *pC;
       BtCursor *pCrsr;
       int res;
       UnpackedRecord r;
-    } bs;
+    } bt;
     struct OP_IdxRowid_stack_vars {
       BtCursor *pCrsr;
       VdbeCursor *pC;
       i64 rowid;
-    } bt;
+    } bu;
     struct OP_IdxGE_stack_vars {
       VdbeCursor *pC;
       int res;
       UnpackedRecord r;
-    } bu;
+    } bv;
     struct OP_Destroy_stack_vars {
       int iMoved;
       int iCnt;
       Vdbe *pVdbe;
       int iDb;
-    } bv;
+    } bw;
     struct OP_Clear_stack_vars {
       int nChange;
-    } bw;
+    } bx;
     struct OP_CreateTable_stack_vars {
       int pgno;
       int flags;
       Db *pDb;
-    } bx;
+    } by;
     struct OP_ParseSchema_stack_vars {
       int iDb;
       const char *zMaster;
       char *zSql;
       InitData initData;
-    } by;
+    } bz;
     struct OP_IntegrityCk_stack_vars {
       int nRoot;      /* Number of tables to check.  (Number of root pages.) */
       int *aRoot;     /* Array of rootpage numbers for tables to be checked */
@@ -66195,14 +64381,14 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
       int nErr;       /* Number of errors reported */
       char *z;        /* Text of the error report */
       Mem *pnErr;     /* Register keeping track of errors remaining */
-    } bz;
+    } ca;
     struct OP_RowSetRead_stack_vars {
       i64 val;
-    } ca;
+    } cb;
     struct OP_RowSetTest_stack_vars {
       int iSet;
       int exists;
-    } cb;
+    } cc;
     struct OP_Program_stack_vars {
       int nMem;               /* Number of memory registers for sub-program */
       int nByte;              /* Bytes of runtime space required for sub-program */
@@ -66212,15 +64398,15 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
       VdbeFrame *pFrame;      /* New vdbe frame to execute in */
       SubProgram *pProgram;   /* Sub-program to execute */
       void *t;                /* Token identifying trigger */
-    } cc;
+    } cd;
     struct OP_Param_stack_vars {
       VdbeFrame *pFrame;
       Mem *pIn;
-    } cd;
+    } ce;
     struct OP_MemMax_stack_vars {
       Mem *pIn1;
       VdbeFrame *pFrame;
-    } ce;
+    } cf;
     struct OP_AggStep_stack_vars {
       int n;
       int i;
@@ -66228,34 +64414,36 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
       Mem *pRec;
       sqlite3_context ctx;
       sqlite3_value **apVal;
-    } cf;
+    } cg;
     struct OP_AggFinal_stack_vars {
       Mem *pMem;
-    } cg;
+    } ch;
     struct OP_Checkpoint_stack_vars {
       int i;                          /* Loop counter */
       int aRes[3];                    /* Results */
       Mem *pMem;                      /* Write results here */
-    } ch;
+    } ci;
     struct OP_JournalMode_stack_vars {
       Btree *pBt;                     /* Btree to change journal mode of */
       Pager *pPager;                  /* Pager associated with pBt */
       int eNew;                       /* New journal mode */
       int eOld;                       /* The old journal mode */
+#ifndef SQLITE_OMIT_WAL
       const char *zFilename;          /* Name of database file for pPager */
-    } ci;
+#endif
+    } cj;
     struct OP_IncrVacuum_stack_vars {
       Btree *pBt;
-    } cj;
+    } ck;
     struct OP_VBegin_stack_vars {
       VTable *pVTab;
-    } ck;
+    } cl;
     struct OP_VOpen_stack_vars {
       VdbeCursor *pCur;
       sqlite3_vtab_cursor *pVtabCursor;
       sqlite3_vtab *pVtab;
       sqlite3_module *pModule;
-    } cl;
+    } cm;
     struct OP_VFilter_stack_vars {
       int nArg;
       int iQuery;
@@ -66268,23 +64456,23 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
       int res;
       int i;
       Mem **apArg;
-    } cm;
+    } cn;
     struct OP_VColumn_stack_vars {
       sqlite3_vtab *pVtab;
       const sqlite3_module *pModule;
       Mem *pDest;
       sqlite3_context sContext;
-    } cn;
+    } co;
     struct OP_VNext_stack_vars {
       sqlite3_vtab *pVtab;
       const sqlite3_module *pModule;
       int res;
       VdbeCursor *pCur;
-    } co;
+    } cp;
     struct OP_VRename_stack_vars {
       sqlite3_vtab *pVtab;
       Mem *pName;
-    } cp;
+    } cq;
     struct OP_VUpdate_stack_vars {
       sqlite3_vtab *pVtab;
       sqlite3_module *pModule;
@@ -66293,11 +64481,11 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
       sqlite_int64 rowid;
       Mem **apArg;
       Mem *pX;
-    } cq;
+    } cr;
     struct OP_Trace_stack_vars {
       char *zTrace;
       char *z;
-    } cr;
+    } cs;
   } u;
   /* End automatically generated code
   ********************************************************************/
@@ -66386,7 +64574,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
     }
 #endif
 
-    /* On any opcode with the "out2-prerelase" tag, free any
+    /* On any opcode with the "out2-prerelease" tag, free any
     ** external allocations out of mem[p2] and set mem[p2] to be
     ** an undefined integer.  Opcodes will either fill in the integer
     ** value or convert mem[p2] to a different type.
@@ -66688,25 +64876,30 @@ case OP_String: {          /* out2-prerelease */
   break;
 }
 
-/* Opcode: Null * P2 P3 * *
+/* Opcode: Null P1 P2 P3 * *
 **
 ** Write a NULL into registers P2.  If P3 greater than P2, then also write
-** NULL into register P3 and ever register in between P2 and P3.  If P3
+** NULL into register P3 and every register in between P2 and P3.  If P3
 ** is less than P2 (typically P3 is zero) then only register P2 is
-** set to NULL
+** set to NULL.
+**
+** If the P1 value is non-zero, then also set the MEM_Cleared flag so that
+** NULL values will not compare equal even if SQLITE_NULLEQ is set on
+** OP_Ne or OP_Eq.
 */
 case OP_Null: {           /* out2-prerelease */
 #if 0  /* local variables moved into u.ab */
   int cnt;
+  u16 nullFlag;
 #endif /* local variables moved into u.ab */
   u.ab.cnt = pOp->p3-pOp->p2;
   assert( pOp->p3<=p->nMem );
-  pOut->flags = MEM_Null;
+  pOut->flags = u.ab.nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
   while( u.ab.cnt>0 ){
     pOut++;
     memAboutToChange(p, pOut);
     VdbeMemRelease(pOut);
-    pOut->flags = MEM_Null;
+    pOut->flags = u.ab.nullFlag;
     u.ab.cnt--;
   }
   break;
@@ -66751,10 +64944,10 @@ case OP_Variable: {            /* out2-prerelease */
 
 /* Opcode: Move P1 P2 P3 * *
 **
-** Move the values in register P1..P1+P3-1 over into
-** registers P2..P2+P3-1.  Registers P1..P1+P1-1 are
+** Move the values in register P1..P1+P3 over into
+** registers P2..P2+P3.  Registers P1..P1+P3 are
 ** left holding a NULL.  It is an error for register ranges
-** P1..P1+P3-1 and P2..P2+P3-1 to overlap.
+** P1..P1+P3 and P2..P2+P3 to overlap.
 */
 case OP_Move: {
 #if 0  /* local variables moved into u.ad */
@@ -66764,7 +64957,7 @@ case OP_Move: {
   int p2;          /* Register to copy to */
 #endif /* local variables moved into u.ad */
 
-  u.ad.n = pOp->p3;
+  u.ad.n = pOp->p3 + 1;
   u.ad.p1 = pOp->p1;
   u.ad.p2 = pOp->p2;
   assert( u.ad.n>0 && u.ad.p1>0 && u.ad.p2>0 );
@@ -66793,20 +64986,33 @@ case OP_Move: {
   break;
 }
 
-/* Opcode: Copy P1 P2 * * *
+/* Opcode: Copy P1 P2 P3 * *
 **
-** Make a copy of register P1 into register P2.
+** Make a copy of registers P1..P1+P3 into registers P2..P2+P3.
 **
 ** This instruction makes a deep copy of the value.  A duplicate
 ** is made of any string or blob constant.  See also OP_SCopy.
 */
-case OP_Copy: {             /* in1, out2 */
+case OP_Copy: {
+#if 0  /* local variables moved into u.ae */
+  int n;
+#endif /* local variables moved into u.ae */
+
+  u.ae.n = pOp->p3;
   pIn1 = &aMem[pOp->p1];
   pOut = &aMem[pOp->p2];
   assert( pOut!=pIn1 );
-  sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
-  Deephemeralize(pOut);
-  REGISTER_TRACE(pOp->p2, pOut);
+  while( 1 ){
+    sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
+    Deephemeralize(pOut);
+#ifdef SQLITE_DEBUG
+    pOut->pScopyFrom = 0;
+#endif
+    REGISTER_TRACE(pOp->p2+pOp->p3-u.ae.n, pOut);
+    if( (u.ae.n--)==0 ) break;
+    pOut++;
+    pIn1++;
+  }
   break;
 }
 
@@ -66843,10 +65049,10 @@ case OP_SCopy: {            /* in1, out2 */
 ** row.
 */
 case OP_ResultRow: {
-#if 0  /* local variables moved into u.ae */
+#if 0  /* local variables moved into u.af */
   Mem *pMem;
   int i;
-#endif /* local variables moved into u.ae */
+#endif /* local variables moved into u.af */
   assert( p->nResColumn==pOp->p2 );
   assert( pOp->p1>0 );
   assert( pOp->p1+pOp->p2<=p->nMem+1 );
@@ -66888,15 +65094,15 @@ case OP_ResultRow: {
   ** and have an assigned type.  The results are de-ephemeralized as
   ** a side effect.
   */
-  u.ae.pMem = p->pResultSet = &aMem[pOp->p1];
-  for(u.ae.i=0; u.ae.i<pOp->p2; u.ae.i++){
-    assert( memIsValid(&u.ae.pMem[u.ae.i]) );
-    Deephemeralize(&u.ae.pMem[u.ae.i]);
-    assert( (u.ae.pMem[u.ae.i].flags & MEM_Ephem)==0
-            || (u.ae.pMem[u.ae.i].flags & (MEM_Str|MEM_Blob))==0 );
-    sqlite3VdbeMemNulTerminate(&u.ae.pMem[u.ae.i]);
-    sqlite3VdbeMemStoreType(&u.ae.pMem[u.ae.i]);
-    REGISTER_TRACE(pOp->p1+u.ae.i, &u.ae.pMem[u.ae.i]);
+  u.af.pMem = p->pResultSet = &aMem[pOp->p1];
+  for(u.af.i=0; u.af.i<pOp->p2; u.af.i++){
+    assert( memIsValid(&u.af.pMem[u.af.i]) );
+    Deephemeralize(&u.af.pMem[u.af.i]);
+    assert( (u.af.pMem[u.af.i].flags & MEM_Ephem)==0
+            || (u.af.pMem[u.af.i].flags & (MEM_Str|MEM_Blob))==0 );
+    sqlite3VdbeMemNulTerminate(&u.af.pMem[u.af.i]);
+    sqlite3VdbeMemStoreType(&u.af.pMem[u.af.i]);
+    REGISTER_TRACE(pOp->p1+u.af.i, &u.af.pMem[u.af.i]);
   }
   if( db->mallocFailed ) goto no_mem;
 
@@ -66920,9 +65126,9 @@ case OP_ResultRow: {
 ** to avoid a memcpy().
 */
 case OP_Concat: {           /* same as TK_CONCAT, in1, in2, out3 */
-#if 0  /* local variables moved into u.af */
+#if 0  /* local variables moved into u.ag */
   i64 nByte;
-#endif /* local variables moved into u.af */
+#endif /* local variables moved into u.ag */
 
   pIn1 = &aMem[pOp->p1];
   pIn2 = &aMem[pOp->p2];
@@ -66935,22 +65141,22 @@ case OP_Concat: {           /* same as TK_CONCAT, in1, in2, out3 */
   if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem;
   Stringify(pIn1, encoding);
   Stringify(pIn2, encoding);
-  u.af.nByte = pIn1->n + pIn2->n;
-  if( u.af.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+  u.ag.nByte = pIn1->n + pIn2->n;
+  if( u.ag.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
     goto too_big;
   }
   MemSetTypeFlag(pOut, MEM_Str);
-  if( sqlite3VdbeMemGrow(pOut, (int)u.af.nByte+2, pOut==pIn2) ){
+  if( sqlite3VdbeMemGrow(pOut, (int)u.ag.nByte+2, pOut==pIn2) ){
     goto no_mem;
   }
   if( pOut!=pIn2 ){
     memcpy(pOut->z, pIn2->z, pIn2->n);
   }
   memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n);
-  pOut->z[u.af.nByte] = 0;
-  pOut->z[u.af.nByte+1] = 0;
+  pOut->z[u.ag.nByte] = 0;
+  pOut->z[u.ag.nByte+1] = 0;
   pOut->flags |= MEM_Term;
-  pOut->n = (int)u.af.nByte;
+  pOut->n = (int)u.ag.nByte;
   pOut->enc = encoding;
   UPDATE_MAX_BLOBSIZE(pOut);
   break;
@@ -66994,76 +65200,79 @@ case OP_Subtract:              /* same as TK_MINUS, in1, in2, out3 */
 case OP_Multiply:              /* same as TK_STAR, in1, in2, out3 */
 case OP_Divide:                /* same as TK_SLASH, in1, in2, out3 */
 case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */
-#if 0  /* local variables moved into u.ag */
+#if 0  /* local variables moved into u.ah */
+  char bIntint;   /* Started out as two integer operands */
   int flags;      /* Combined MEM_* flags from both inputs */
   i64 iA;         /* Integer value of left operand */
   i64 iB;         /* Integer value of right operand */
   double rA;      /* Real value of left operand */
   double rB;      /* Real value of right operand */
-#endif /* local variables moved into u.ag */
+#endif /* local variables moved into u.ah */
 
   pIn1 = &aMem[pOp->p1];
   applyNumericAffinity(pIn1);
   pIn2 = &aMem[pOp->p2];
   applyNumericAffinity(pIn2);
   pOut = &aMem[pOp->p3];
-  u.ag.flags = pIn1->flags | pIn2->flags;
-  if( (u.ag.flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
+  u.ah.flags = pIn1->flags | pIn2->flags;
+  if( (u.ah.flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
   if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
-    u.ag.iA = pIn1->u.i;
-    u.ag.iB = pIn2->u.i;
+    u.ah.iA = pIn1->u.i;
+    u.ah.iB = pIn2->u.i;
+    u.ah.bIntint = 1;
     switch( pOp->opcode ){
-      case OP_Add:       if( sqlite3AddInt64(&u.ag.iB,u.ag.iA) ) goto fp_math;  break;
-      case OP_Subtract:  if( sqlite3SubInt64(&u.ag.iB,u.ag.iA) ) goto fp_math;  break;
-      case OP_Multiply:  if( sqlite3MulInt64(&u.ag.iB,u.ag.iA) ) goto fp_math;  break;
+      case OP_Add:       if( sqlite3AddInt64(&u.ah.iB,u.ah.iA) ) goto fp_math;  break;
+      case OP_Subtract:  if( sqlite3SubInt64(&u.ah.iB,u.ah.iA) ) goto fp_math;  break;
+      case OP_Multiply:  if( sqlite3MulInt64(&u.ah.iB,u.ah.iA) ) goto fp_math;  break;
       case OP_Divide: {
-        if( u.ag.iA==0 ) goto arithmetic_result_is_null;
-        if( u.ag.iA==-1 && u.ag.iB==SMALLEST_INT64 ) goto fp_math;
-        u.ag.iB /= u.ag.iA;
+        if( u.ah.iA==0 ) goto arithmetic_result_is_null;
+        if( u.ah.iA==-1 && u.ah.iB==SMALLEST_INT64 ) goto fp_math;
+        u.ah.iB /= u.ah.iA;
         break;
       }
       default: {
-        if( u.ag.iA==0 ) goto arithmetic_result_is_null;
-        if( u.ag.iA==-1 ) u.ag.iA = 1;
-        u.ag.iB %= u.ag.iA;
+        if( u.ah.iA==0 ) goto arithmetic_result_is_null;
+        if( u.ah.iA==-1 ) u.ah.iA = 1;
+        u.ah.iB %= u.ah.iA;
         break;
       }
     }
-    pOut->u.i = u.ag.iB;
+    pOut->u.i = u.ah.iB;
     MemSetTypeFlag(pOut, MEM_Int);
   }else{
+    u.ah.bIntint = 0;
 fp_math:
-    u.ag.rA = sqlite3VdbeRealValue(pIn1);
-    u.ag.rB = sqlite3VdbeRealValue(pIn2);
+    u.ah.rA = sqlite3VdbeRealValue(pIn1);
+    u.ah.rB = sqlite3VdbeRealValue(pIn2);
     switch( pOp->opcode ){
-      case OP_Add:         u.ag.rB += u.ag.rA;       break;
-      case OP_Subtract:    u.ag.rB -= u.ag.rA;       break;
-      case OP_Multiply:    u.ag.rB *= u.ag.rA;       break;
+      case OP_Add:         u.ah.rB += u.ah.rA;       break;
+      case OP_Subtract:    u.ah.rB -= u.ah.rA;       break;
+      case OP_Multiply:    u.ah.rB *= u.ah.rA;       break;
       case OP_Divide: {
         /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
-        if( u.ag.rA==(double)0 ) goto arithmetic_result_is_null;
-        u.ag.rB /= u.ag.rA;
+        if( u.ah.rA==(double)0 ) goto arithmetic_result_is_null;
+        u.ah.rB /= u.ah.rA;
         break;
       }
       default: {
-        u.ag.iA = (i64)u.ag.rA;
-        u.ag.iB = (i64)u.ag.rB;
-        if( u.ag.iA==0 ) goto arithmetic_result_is_null;
-        if( u.ag.iA==-1 ) u.ag.iA = 1;
-        u.ag.rB = (double)(u.ag.iB % u.ag.iA);
+        u.ah.iA = (i64)u.ah.rA;
+        u.ah.iB = (i64)u.ah.rB;
+        if( u.ah.iA==0 ) goto arithmetic_result_is_null;
+        if( u.ah.iA==-1 ) u.ah.iA = 1;
+        u.ah.rB = (double)(u.ah.iB % u.ah.iA);
         break;
       }
     }
 #ifdef SQLITE_OMIT_FLOATING_POINT
-    pOut->u.i = u.ag.rB;
+    pOut->u.i = u.ah.rB;
     MemSetTypeFlag(pOut, MEM_Int);
 #else
-    if( sqlite3IsNaN(u.ag.rB) ){
+    if( sqlite3IsNaN(u.ah.rB) ){
       goto arithmetic_result_is_null;
     }
-    pOut->r = u.ag.rB;
+    pOut->r = u.ah.rB;
     MemSetTypeFlag(pOut, MEM_Real);
-    if( (u.ag.flags & MEM_Real)==0 ){
+    if( (u.ah.flags & MEM_Real)==0 && !u.ah.bIntint ){
       sqlite3VdbeIntegerAffinity(pOut);
     }
 #endif
@@ -67115,70 +65324,70 @@ case OP_CollSeq: {
 ** See also: AggStep and AggFinal
 */
 case OP_Function: {
-#if 0  /* local variables moved into u.ah */
+#if 0  /* local variables moved into u.ai */
   int i;
   Mem *pArg;
   sqlite3_context ctx;
   sqlite3_value **apVal;
   int n;
-#endif /* local variables moved into u.ah */
+#endif /* local variables moved into u.ai */
 
-  u.ah.n = pOp->p5;
-  u.ah.apVal = p->apArg;
-  assert( u.ah.apVal || u.ah.n==0 );
+  u.ai.n = pOp->p5;
+  u.ai.apVal = p->apArg;
+  assert( u.ai.apVal || u.ai.n==0 );
   assert( pOp->p3>0 && pOp->p3<=p->nMem );
   pOut = &aMem[pOp->p3];
   memAboutToChange(p, pOut);
 
-  assert( u.ah.n==0 || (pOp->p2>0 && pOp->p2+u.ah.n<=p->nMem+1) );
-  assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+u.ah.n );
-  u.ah.pArg = &aMem[pOp->p2];
-  for(u.ah.i=0; u.ah.i<u.ah.n; u.ah.i++, u.ah.pArg++){
-    assert( memIsValid(u.ah.pArg) );
-    u.ah.apVal[u.ah.i] = u.ah.pArg;
-    Deephemeralize(u.ah.pArg);
-    sqlite3VdbeMemStoreType(u.ah.pArg);
-    REGISTER_TRACE(pOp->p2+u.ah.i, u.ah.pArg);
+  assert( u.ai.n==0 || (pOp->p2>0 && pOp->p2+u.ai.n<=p->nMem+1) );
+  assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+u.ai.n );
+  u.ai.pArg = &aMem[pOp->p2];
+  for(u.ai.i=0; u.ai.i<u.ai.n; u.ai.i++, u.ai.pArg++){
+    assert( memIsValid(u.ai.pArg) );
+    u.ai.apVal[u.ai.i] = u.ai.pArg;
+    Deephemeralize(u.ai.pArg);
+    sqlite3VdbeMemStoreType(u.ai.pArg);
+    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.ah.ctx.pFunc = pOp->p4.pFunc;
-    u.ah.ctx.pVdbeFunc = 0;
+    u.ai.ctx.pFunc = pOp->p4.pFunc;
+    u.ai.ctx.pVdbeFunc = 0;
   }else{
-    u.ah.ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.pVdbeFunc;
-    u.ah.ctx.pFunc = u.ah.ctx.pVdbeFunc->pFunc;
+    u.ai.ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.pVdbeFunc;
+    u.ai.ctx.pFunc = u.ai.ctx.pVdbeFunc->pFunc;
   }
 
-  u.ah.ctx.s.flags = MEM_Null;
-  u.ah.ctx.s.db = db;
-  u.ah.ctx.s.xDel = 0;
-  u.ah.ctx.s.zMalloc = 0;
+  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;
 
   /* The output cell may already have a buffer allocated. Move
-  ** the pointer to u.ah.ctx.s so in case the user-function can use
+  ** the pointer to u.ai.ctx.s so in case the user-function can use
   ** the already allocated buffer instead of allocating a new one.
   */
-  sqlite3VdbeMemMove(&u.ah.ctx.s, pOut);
-  MemSetTypeFlag(&u.ah.ctx.s, MEM_Null);
+  sqlite3VdbeMemMove(&u.ai.ctx.s, pOut);
+  MemSetTypeFlag(&u.ai.ctx.s, MEM_Null);
 
-  u.ah.ctx.isError = 0;
-  if( u.ah.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
+  u.ai.ctx.isError = 0;
+  if( u.ai.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
     assert( pOp>aOp );
     assert( pOp[-1].p4type==P4_COLLSEQ );
     assert( pOp[-1].opcode==OP_CollSeq );
-    u.ah.ctx.pColl = pOp[-1].p4.pColl;
+    u.ai.ctx.pColl = pOp[-1].p4.pColl;
   }
   db->lastRowid = lastRowid;
-  (*u.ah.ctx.pFunc->xFunc)(&u.ah.ctx, u.ah.n, u.ah.apVal); /* IMP: R-24505-23230 */
+  (*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.ah.ctx.pVdbeFunc ){
-    sqlite3VdbeDeleteAuxData(u.ah.ctx.pVdbeFunc, pOp->p1);
-    pOp->p4.pVdbeFunc = u.ah.ctx.pVdbeFunc;
+  if( u.ai.ctx.pVdbeFunc ){
+    sqlite3VdbeDeleteAuxData(u.ai.ctx.pVdbeFunc, pOp->p1);
+    pOp->p4.pVdbeFunc = u.ai.ctx.pVdbeFunc;
     pOp->p4type = P4_VDBEFUNC;
   }
 
@@ -67188,19 +65397,19 @@ case OP_Function: {
     ** to return a value. The following call releases any resources
     ** associated with such a value.
     */
-    sqlite3VdbeMemRelease(&u.ah.ctx.s);
+    sqlite3VdbeMemRelease(&u.ai.ctx.s);
     goto no_mem;
   }
 
   /* If the function returned an error, throw an exception */
-  if( u.ah.ctx.isError ){
-    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ah.ctx.s));
-    rc = u.ah.ctx.isError;
+  if( u.ai.ctx.isError ){
+    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ai.ctx.s));
+    rc = u.ai.ctx.isError;
   }
 
   /* Copy the result of the function into register P3 */
-  sqlite3VdbeChangeEncoding(&u.ah.ctx.s, encoding);
-  sqlite3VdbeMemMove(pOut, &u.ah.ctx.s);
+  sqlite3VdbeChangeEncoding(&u.ai.ctx.s, encoding);
+  sqlite3VdbeMemMove(pOut, &u.ai.ctx.s);
   if( sqlite3VdbeMemTooBig(pOut) ){
     goto too_big;
   }
@@ -67248,12 +65457,12 @@ case OP_BitAnd:                 /* same as TK_BITAND, in1, in2, out3 */
 case OP_BitOr:                  /* same as TK_BITOR, in1, in2, out3 */
 case OP_ShiftLeft:              /* same as TK_LSHIFT, in1, in2, out3 */
 case OP_ShiftRight: {           /* same as TK_RSHIFT, in1, in2, out3 */
-#if 0  /* local variables moved into u.ai */
+#if 0  /* local variables moved into u.aj */
   i64 iA;
   u64 uA;
   i64 iB;
   u8 op;
-#endif /* local variables moved into u.ai */
+#endif /* local variables moved into u.aj */
 
   pIn1 = &aMem[pOp->p1];
   pIn2 = &aMem[pOp->p2];
@@ -67262,38 +65471,38 @@ case OP_ShiftRight: {           /* same as TK_RSHIFT, in1, in2, out3 */
     sqlite3VdbeMemSetNull(pOut);
     break;
   }
-  u.ai.iA = sqlite3VdbeIntValue(pIn2);
-  u.ai.iB = sqlite3VdbeIntValue(pIn1);
-  u.ai.op = pOp->opcode;
-  if( u.ai.op==OP_BitAnd ){
-    u.ai.iA &= u.ai.iB;
-  }else if( u.ai.op==OP_BitOr ){
-    u.ai.iA |= u.ai.iB;
-  }else if( u.ai.iB!=0 ){
-    assert( u.ai.op==OP_ShiftRight || u.ai.op==OP_ShiftLeft );
+  u.aj.iA = sqlite3VdbeIntValue(pIn2);
+  u.aj.iB = sqlite3VdbeIntValue(pIn1);
+  u.aj.op = pOp->opcode;
+  if( u.aj.op==OP_BitAnd ){
+    u.aj.iA &= u.aj.iB;
+  }else if( u.aj.op==OP_BitOr ){
+    u.aj.iA |= u.aj.iB;
+  }else if( u.aj.iB!=0 ){
+    assert( u.aj.op==OP_ShiftRight || u.aj.op==OP_ShiftLeft );
 
     /* If shifting by a negative amount, shift in the other direction */
-    if( u.ai.iB<0 ){
+    if( u.aj.iB<0 ){
       assert( OP_ShiftRight==OP_ShiftLeft+1 );
-      u.ai.op = 2*OP_ShiftLeft + 1 - u.ai.op;
-      u.ai.iB = u.ai.iB>(-64) ? -u.ai.iB : 64;
+      u.aj.op = 2*OP_ShiftLeft + 1 - u.aj.op;
+      u.aj.iB = u.aj.iB>(-64) ? -u.aj.iB : 64;
     }
 
-    if( u.ai.iB>=64 ){
-      u.ai.iA = (u.ai.iA>=0 || u.ai.op==OP_ShiftLeft) ? 0 : -1;
+    if( u.aj.iB>=64 ){
+      u.aj.iA = (u.aj.iA>=0 || u.aj.op==OP_ShiftLeft) ? 0 : -1;
     }else{
-      memcpy(&u.ai.uA, &u.ai.iA, sizeof(u.ai.uA));
-      if( u.ai.op==OP_ShiftLeft ){
-        u.ai.uA <<= u.ai.iB;
+      memcpy(&u.aj.uA, &u.aj.iA, sizeof(u.aj.uA));
+      if( u.aj.op==OP_ShiftLeft ){
+        u.aj.uA <<= u.aj.iB;
       }else{
-        u.ai.uA >>= u.ai.iB;
+        u.aj.uA >>= u.aj.iB;
         /* Sign-extend on a right shift of a negative number */
-        if( u.ai.iA<0 ) u.ai.uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-u.ai.iB);
+        if( u.aj.iA<0 ) u.aj.uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-u.aj.iB);
       }
-      memcpy(&u.ai.iA, &u.ai.uA, sizeof(u.ai.iA));
+      memcpy(&u.aj.iA, &u.aj.uA, sizeof(u.aj.iA));
     }
   }
-  pOut->u.i = u.ai.iA;
+  pOut->u.i = u.aj.iA;
   MemSetTypeFlag(pOut, MEM_Int);
   break;
 }
@@ -67485,6 +65694,10 @@ case OP_ToReal: {                  /* same as TK_TO_REAL, in1 */
 **
 ** If the SQLITE_STOREP2 bit of P5 is set, then do not jump.  Instead,
 ** store a boolean result (either 0, or 1, or NULL) in register P2.
+**
+** If the SQLITE_NULLEQ bit is set in P5, then NULL values are considered
+** equal to one another, provided that they do not have their MEM_Cleared
+** bit set.
 */
 /* Opcode: Ne P1 P2 P3 P4 P5
 **
@@ -67534,18 +65747,18 @@ case OP_Lt:               /* same as TK_LT, jump, in1, in3 */
 case OP_Le:               /* same as TK_LE, jump, in1, in3 */
 case OP_Gt:               /* same as TK_GT, jump, in1, in3 */
 case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */
-#if 0  /* local variables moved into u.aj */
+#if 0  /* local variables moved into u.ak */
   int res;            /* Result of the comparison of pIn1 against pIn3 */
   char affinity;      /* Affinity to use for comparison */
   u16 flags1;         /* Copy of initial value of pIn1->flags */
   u16 flags3;         /* Copy of initial value of pIn3->flags */
-#endif /* local variables moved into u.aj */
+#endif /* local variables moved into u.ak */
 
   pIn1 = &aMem[pOp->p1];
   pIn3 = &aMem[pOp->p3];
-  u.aj.flags1 = pIn1->flags;
-  u.aj.flags3 = pIn3->flags;
-  if( (u.aj.flags1 | u.aj.flags3)&MEM_Null ){
+  u.ak.flags1 = pIn1->flags;
+  u.ak.flags3 = pIn3->flags;
+  if( (u.ak.flags1 | u.ak.flags3)&MEM_Null ){
     /* One or both operands are NULL */
     if( pOp->p5 & SQLITE_NULLEQ ){
       /* If SQLITE_NULLEQ is set (which will only happen if the operator is
@@ -67553,7 +65766,15 @@ case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */
       ** or not both operands are null.
       */
       assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
-      u.aj.res = (u.aj.flags1 & u.aj.flags3 & MEM_Null)==0;
+      assert( (u.ak.flags1 & MEM_Cleared)==0 );
+      if( (u.ak.flags1&MEM_Null)!=0
+       && (u.ak.flags3&MEM_Null)!=0
+       && (u.ak.flags3&MEM_Cleared)==0
+      ){
+        u.ak.res = 0;  /* Results are equal */
+      }else{
+        u.ak.res = 1;  /* Results are not equal */
+      }
     }else{
       /* SQLITE_NULLEQ is clear and at least one operand is NULL,
       ** then the result is always NULL.
@@ -67570,40 +65791,40 @@ case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */
     }
   }else{
     /* Neither operand is NULL.  Do a comparison. */
-    u.aj.affinity = pOp->p5 & SQLITE_AFF_MASK;
-    if( u.aj.affinity ){
-      applyAffinity(pIn1, u.aj.affinity, encoding);
-      applyAffinity(pIn3, u.aj.affinity, encoding);
+    u.ak.affinity = pOp->p5 & SQLITE_AFF_MASK;
+    if( u.ak.affinity ){
+      applyAffinity(pIn1, u.ak.affinity, encoding);
+      applyAffinity(pIn3, u.ak.affinity, encoding);
       if( db->mallocFailed ) goto no_mem;
     }
 
     assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
     ExpandBlob(pIn1);
     ExpandBlob(pIn3);
-    u.aj.res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
+    u.ak.res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
   }
   switch( pOp->opcode ){
-    case OP_Eq:    u.aj.res = u.aj.res==0;     break;
-    case OP_Ne:    u.aj.res = u.aj.res!=0;     break;
-    case OP_Lt:    u.aj.res = u.aj.res<0;      break;
-    case OP_Le:    u.aj.res = u.aj.res<=0;     break;
-    case OP_Gt:    u.aj.res = u.aj.res>0;      break;
-    default:       u.aj.res = u.aj.res>=0;     break;
+    case OP_Eq:    u.ak.res = u.ak.res==0;     break;
+    case OP_Ne:    u.ak.res = u.ak.res!=0;     break;
+    case OP_Lt:    u.ak.res = u.ak.res<0;      break;
+    case OP_Le:    u.ak.res = u.ak.res<=0;     break;
+    case OP_Gt:    u.ak.res = u.ak.res>0;      break;
+    default:       u.ak.res = u.ak.res>=0;     break;
   }
 
   if( pOp->p5 & SQLITE_STOREP2 ){
     pOut = &aMem[pOp->p2];
     memAboutToChange(p, pOut);
     MemSetTypeFlag(pOut, MEM_Int);
-    pOut->u.i = u.aj.res;
+    pOut->u.i = u.ak.res;
     REGISTER_TRACE(pOp->p2, pOut);
-  }else if( u.aj.res ){
+  }else if( u.ak.res ){
     pc = pOp->p2-1;
   }
 
   /* Undo any changes made by applyAffinity() to the input registers. */
-  pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (u.aj.flags1&MEM_TypeMask);
-  pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (u.aj.flags3&MEM_TypeMask);
+  pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (u.ak.flags1&MEM_TypeMask);
+  pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (u.ak.flags3&MEM_TypeMask);
   break;
 }
 
@@ -67612,9 +65833,9 @@ case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */
 ** Set the permutation used by the OP_Compare operator to be the array
 ** of integers in P4.
 **
-** The permutation is only valid until the next OP_Permutation, OP_Compare,
-** OP_Halt, or OP_ResultRow.  Typically the OP_Permutation should occur
-** immediately prior to the OP_Compare.
+** The permutation is only valid until the next OP_Compare that has
+** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should 
+** occur immediately prior to the OP_Compare.
 */
 case OP_Permutation: {
   assert( pOp->p4type==P4_INTARRAY );
@@ -67623,12 +65844,17 @@ case OP_Permutation: {
   break;
 }
 
-/* Opcode: Compare P1 P2 P3 P4 *
+/* Opcode: Compare P1 P2 P3 P4 P5
 **
 ** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this
 ** vector "A") and in reg(P2)..reg(P2+P3-1) ("B").  Save the result of
 ** the comparison for use by the next OP_Jump instruct.
 **
+** If P5 has the OPFLAG_PERMUTE bit set, then the order of comparison is
+** determined by the most recent OP_Permutation operator.  If the
+** OPFLAG_PERMUTE bit is clear, then register are compared in sequential
+** order.
+**
 ** P4 is a KeyInfo structure that defines collating sequences and sort
 ** orders for the comparison.  The permutation applies to registers
 ** only.  The KeyInfo elements are used sequentially.
@@ -67638,7 +65864,7 @@ case OP_Permutation: {
 ** and strings are less than blobs.
 */
 case OP_Compare: {
-#if 0  /* local variables moved into u.ak */
+#if 0  /* local variables moved into u.al */
   int n;
   int i;
   int p1;
@@ -67647,37 +65873,38 @@ case OP_Compare: {
   int idx;
   CollSeq *pColl;    /* Collating sequence to use on this term */
   int bRev;          /* True for DESCENDING sort order */
-#endif /* local variables moved into u.ak */
+#endif /* local variables moved into u.al */
 
-  u.ak.n = pOp->p3;
-  u.ak.pKeyInfo = pOp->p4.pKeyInfo;
-  assert( u.ak.n>0 );
-  assert( u.ak.pKeyInfo!=0 );
-  u.ak.p1 = pOp->p1;
-  u.ak.p2 = pOp->p2;
+  if( (pOp->p5 & OPFLAG_PERMUTE)==0 ) aPermute = 0;
+  u.al.n = pOp->p3;
+  u.al.pKeyInfo = pOp->p4.pKeyInfo;
+  assert( u.al.n>0 );
+  assert( u.al.pKeyInfo!=0 );
+  u.al.p1 = pOp->p1;
+  u.al.p2 = pOp->p2;
 #if SQLITE_DEBUG
   if( aPermute ){
     int k, mx = 0;
-    for(k=0; k<u.ak.n; k++) if( aPermute[k]>mx ) mx = aPermute[k];
-    assert( u.ak.p1>0 && u.ak.p1+mx<=p->nMem+1 );
-    assert( u.ak.p2>0 && u.ak.p2+mx<=p->nMem+1 );
+    for(k=0; k<u.al.n; k++) if( aPermute[k]>mx ) mx = aPermute[k];
+    assert( u.al.p1>0 && u.al.p1+mx<=p->nMem+1 );
+    assert( u.al.p2>0 && u.al.p2+mx<=p->nMem+1 );
   }else{
-    assert( u.ak.p1>0 && u.ak.p1+u.ak.n<=p->nMem+1 );
-    assert( u.ak.p2>0 && u.ak.p2+u.ak.n<=p->nMem+1 );
+    assert( u.al.p1>0 && u.al.p1+u.al.n<=p->nMem+1 );
+    assert( u.al.p2>0 && u.al.p2+u.al.n<=p->nMem+1 );
   }
 #endif /* SQLITE_DEBUG */
-  for(u.ak.i=0; u.ak.i<u.ak.n; u.ak.i++){
-    u.ak.idx = aPermute ? aPermute[u.ak.i] : u.ak.i;
-    assert( memIsValid(&aMem[u.ak.p1+u.ak.idx]) );
-    assert( memIsValid(&aMem[u.ak.p2+u.ak.idx]) );
-    REGISTER_TRACE(u.ak.p1+u.ak.idx, &aMem[u.ak.p1+u.ak.idx]);
-    REGISTER_TRACE(u.ak.p2+u.ak.idx, &aMem[u.ak.p2+u.ak.idx]);
-    assert( u.ak.i<u.ak.pKeyInfo->nField );
-    u.ak.pColl = u.ak.pKeyInfo->aColl[u.ak.i];
-    u.ak.bRev = u.ak.pKeyInfo->aSortOrder[u.ak.i];
-    iCompare = sqlite3MemCompare(&aMem[u.ak.p1+u.ak.idx], &aMem[u.ak.p2+u.ak.idx], u.ak.pColl);
+  for(u.al.i=0; u.al.i<u.al.n; u.al.i++){
+    u.al.idx = aPermute ? aPermute[u.al.i] : u.al.i;
+    assert( memIsValid(&aMem[u.al.p1+u.al.idx]) );
+    assert( memIsValid(&aMem[u.al.p2+u.al.idx]) );
+    REGISTER_TRACE(u.al.p1+u.al.idx, &aMem[u.al.p1+u.al.idx]);
+    REGISTER_TRACE(u.al.p2+u.al.idx, &aMem[u.al.p2+u.al.idx]);
+    assert( u.al.i<u.al.pKeyInfo->nField );
+    u.al.pColl = u.al.pKeyInfo->aColl[u.al.i];
+    u.al.bRev = u.al.pKeyInfo->aSortOrder[u.al.i];
+    iCompare = sqlite3MemCompare(&aMem[u.al.p1+u.al.idx], &aMem[u.al.p2+u.al.idx], u.al.pColl);
     if( iCompare ){
-      if( u.ak.bRev ) iCompare = -iCompare;
+      if( u.al.bRev ) iCompare = -iCompare;
       break;
     }
   }
@@ -67722,35 +65949,35 @@ case OP_Jump: {             /* jump */
 */
 case OP_And:              /* same as TK_AND, in1, in2, out3 */
 case OP_Or: {             /* same as TK_OR, in1, in2, out3 */
-#if 0  /* local variables moved into u.al */
+#if 0  /* local variables moved into u.am */
   int v1;    /* Left operand:  0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
   int v2;    /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
-#endif /* local variables moved into u.al */
+#endif /* local variables moved into u.am */
 
   pIn1 = &aMem[pOp->p1];
   if( pIn1->flags & MEM_Null ){
-    u.al.v1 = 2;
+    u.am.v1 = 2;
   }else{
-    u.al.v1 = sqlite3VdbeIntValue(pIn1)!=0;
+    u.am.v1 = sqlite3VdbeIntValue(pIn1)!=0;
   }
   pIn2 = &aMem[pOp->p2];
   if( pIn2->flags & MEM_Null ){
-    u.al.v2 = 2;
+    u.am.v2 = 2;
   }else{
-    u.al.v2 = sqlite3VdbeIntValue(pIn2)!=0;
+    u.am.v2 = sqlite3VdbeIntValue(pIn2)!=0;
   }
   if( pOp->opcode==OP_And ){
     static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };
-    u.al.v1 = and_logic[u.al.v1*3+u.al.v2];
+    u.am.v1 = and_logic[u.am.v1*3+u.am.v2];
   }else{
     static const unsigned char or_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 };
-    u.al.v1 = or_logic[u.al.v1*3+u.al.v2];
+    u.am.v1 = or_logic[u.am.v1*3+u.am.v2];
   }
   pOut = &aMem[pOp->p3];
-  if( u.al.v1==2 ){
+  if( u.am.v1==2 ){
     MemSetTypeFlag(pOut, MEM_Null);
   }else{
-    pOut->u.i = u.al.v1;
+    pOut->u.i = u.am.v1;
     MemSetTypeFlag(pOut, MEM_Int);
   }
   break;
@@ -67794,8 +66021,6 @@ case OP_BitNot: {             /* same as TK_BITNOT, in1, out2 */
 **
 ** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise,
 ** set the flag and fall through to the next instruction.
-**
-** See also: JumpOnce
 */
 case OP_Once: {             /* jump */
   assert( pOp->p1<p->nOnceFlag );
@@ -67821,21 +66046,21 @@ case OP_Once: {             /* jump */
 */
 case OP_If:                 /* jump, in1 */
 case OP_IfNot: {            /* jump, in1 */
-#if 0  /* local variables moved into u.am */
+#if 0  /* local variables moved into u.an */
   int c;
-#endif /* local variables moved into u.am */
+#endif /* local variables moved into u.an */
   pIn1 = &aMem[pOp->p1];
   if( pIn1->flags & MEM_Null ){
-    u.am.c = pOp->p3;
+    u.an.c = pOp->p3;
   }else{
 #ifdef SQLITE_OMIT_FLOATING_POINT
-    u.am.c = sqlite3VdbeIntValue(pIn1)!=0;
+    u.an.c = sqlite3VdbeIntValue(pIn1)!=0;
 #else
-    u.am.c = sqlite3VdbeRealValue(pIn1)!=0.0;
+    u.an.c = sqlite3VdbeRealValue(pIn1)!=0.0;
 #endif
-    if( pOp->opcode==OP_IfNot ) u.am.c = !u.am.c;
+    if( pOp->opcode==OP_IfNot ) u.an.c = !u.an.c;
   }
-  if( u.am.c ){
+  if( u.an.c ){
     pc = pOp->p2-1;
   }
   break;
@@ -67890,7 +66115,7 @@ case OP_NotNull: {            /* same as TK_NOTNULL, jump, in1 */
 ** skipped for length() and all content loading can be skipped for typeof().
 */
 case OP_Column: {
-#if 0  /* local variables moved into u.an */
+#if 0  /* local variables moved into u.ao */
   u32 payloadSize;   /* Number of bytes in the record */
   i64 payloadSize64; /* Number of bytes in the record */
   int p1;            /* P1 value of the opcode */
@@ -67914,126 +66139,131 @@ case OP_Column: {
   int avail;         /* Number of bytes of available data */
   u32 t;             /* A type code from the record header */
   Mem *pReg;         /* PseudoTable input register */
-#endif /* local variables moved into u.an */
+#endif /* local variables moved into u.ao */
 
 
-  u.an.p1 = pOp->p1;
-  u.an.p2 = pOp->p2;
-  u.an.pC = 0;
-  memset(&u.an.sMem, 0, sizeof(u.an.sMem));
-  assert( u.an.p1<p->nCursor );
+  u.ao.p1 = pOp->p1;
+  u.ao.p2 = pOp->p2;
+  u.ao.pC = 0;
+  memset(&u.ao.sMem, 0, sizeof(u.ao.sMem));
+  assert( u.ao.p1<p->nCursor );
   assert( pOp->p3>0 && pOp->p3<=p->nMem );
-  u.an.pDest = &aMem[pOp->p3];
-  memAboutToChange(p, u.an.pDest);
-  u.an.zRec = 0;
+  u.ao.pDest = &aMem[pOp->p3];
+  memAboutToChange(p, u.ao.pDest);
+  u.ao.zRec = 0;
 
-  /* This block sets the variable u.an.payloadSize to be the total number of
+  /* This block sets the variable u.ao.payloadSize to be the total number of
   ** bytes in the record.
   **
-  ** u.an.zRec is set to be the complete text of the record if it is available.
+  ** u.ao.zRec is set to be the complete text of the record if it is available.
   ** The complete record text is always available for pseudo-tables
   ** If the record is stored in a cursor, the complete record text
-  ** might be available in the  u.an.pC->aRow cache.  Or it might not be.
-  ** If the data is unavailable,  u.an.zRec is set to NULL.
+  ** might be available in the  u.ao.pC->aRow cache.  Or it might not be.
+  ** If the data is unavailable,  u.ao.zRec is set to NULL.
   **
   ** We also compute the number of columns in the record.  For cursors,
   ** the number of columns is stored in the VdbeCursor.nField element.
   */
-  u.an.pC = p->apCsr[u.an.p1];
-  assert( u.an.pC!=0 );
+  u.ao.pC = p->apCsr[u.ao.p1];
+  assert( u.ao.pC!=0 );
 #ifndef SQLITE_OMIT_VIRTUALTABLE
-  assert( u.an.pC->pVtabCursor==0 );
+  assert( u.ao.pC->pVtabCursor==0 );
 #endif
-  u.an.pCrsr = u.an.pC->pCursor;
-  if( u.an.pCrsr!=0 ){
+  u.ao.pCrsr = u.ao.pC->pCursor;
+  if( u.ao.pCrsr!=0 ){
     /* The record is stored in a B-Tree */
-    rc = sqlite3VdbeCursorMoveto(u.an.pC);
+    rc = sqlite3VdbeCursorMoveto(u.ao.pC);
     if( rc ) goto abort_due_to_error;
-    if( u.an.pC->nullRow ){
-      u.an.payloadSize = 0;
-    }else if( u.an.pC->cacheStatus==p->cacheCtr ){
-      u.an.payloadSize = u.an.pC->payloadSize;
-      u.an.zRec = (char*)u.an.pC->aRow;
-    }else if( u.an.pC->isIndex ){
-      assert( sqlite3BtreeCursorIsValid(u.an.pCrsr) );
-      VVA_ONLY(rc =) sqlite3BtreeKeySize(u.an.pCrsr, &u.an.payloadSize64);
+    if( u.ao.pC->nullRow ){
+      u.ao.payloadSize = 0;
+    }else if( u.ao.pC->cacheStatus==p->cacheCtr ){
+      u.ao.payloadSize = u.ao.pC->payloadSize;
+      u.ao.zRec = (char*)u.ao.pC->aRow;
+    }else if( u.ao.pC->isIndex ){
+      assert( sqlite3BtreeCursorIsValid(u.ao.pCrsr) );
+      VVA_ONLY(rc =) sqlite3BtreeKeySize(u.ao.pCrsr, &u.ao.payloadSize64);
       assert( rc==SQLITE_OK );   /* True because of CursorMoveto() call above */
       /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the
-      ** payload size, so it is impossible for u.an.payloadSize64 to be
+      ** payload size, so it is impossible for u.ao.payloadSize64 to be
       ** larger than 32 bits. */
-      assert( (u.an.payloadSize64 & SQLITE_MAX_U32)==(u64)u.an.payloadSize64 );
-      u.an.payloadSize = (u32)u.an.payloadSize64;
+      assert( (u.ao.payloadSize64 & SQLITE_MAX_U32)==(u64)u.ao.payloadSize64 );
+      u.ao.payloadSize = (u32)u.ao.payloadSize64;
     }else{
-      assert( sqlite3BtreeCursorIsValid(u.an.pCrsr) );
-      VVA_ONLY(rc =) sqlite3BtreeDataSize(u.an.pCrsr, &u.an.payloadSize);
+      assert( sqlite3BtreeCursorIsValid(u.ao.pCrsr) );
+      VVA_ONLY(rc =) sqlite3BtreeDataSize(u.ao.pCrsr, &u.ao.payloadSize);
       assert( rc==SQLITE_OK );   /* DataSize() cannot fail */
     }
-  }else if( ALWAYS(u.an.pC->pseudoTableReg>0) ){
-    u.an.pReg = &aMem[u.an.pC->pseudoTableReg];
-    assert( u.an.pReg->flags & MEM_Blob );
-    assert( memIsValid(u.an.pReg) );
-    u.an.payloadSize = u.an.pReg->n;
-    u.an.zRec = u.an.pReg->z;
-    u.an.pC->cacheStatus = (pOp->p5&OPFLAG_CLEARCACHE) ? CACHE_STALE : p->cacheCtr;
-    assert( u.an.payloadSize==0 || u.an.zRec!=0 );
+  }else if( ALWAYS(u.ao.pC->pseudoTableReg>0) ){
+    u.ao.pReg = &aMem[u.ao.pC->pseudoTableReg];
+    if( u.ao.pC->multiPseudo ){
+      sqlite3VdbeMemShallowCopy(u.ao.pDest, u.ao.pReg+u.ao.p2, MEM_Ephem);
+      Deephemeralize(u.ao.pDest);
+      goto op_column_out;
+    }
+    assert( u.ao.pReg->flags & MEM_Blob );
+    assert( memIsValid(u.ao.pReg) );
+    u.ao.payloadSize = u.ao.pReg->n;
+    u.ao.zRec = u.ao.pReg->z;
+    u.ao.pC->cacheStatus = (pOp->p5&OPFLAG_CLEARCACHE) ? CACHE_STALE : p->cacheCtr;
+    assert( u.ao.payloadSize==0 || u.ao.zRec!=0 );
   }else{
     /* Consider the row to be NULL */
-    u.an.payloadSize = 0;
+    u.ao.payloadSize = 0;
   }
 
-  /* If u.an.payloadSize is 0, then just store a NULL.  This can happen because of
+  /* If u.ao.payloadSize is 0, then just store a NULL.  This can happen because of
   ** nullRow or because of a corrupt database. */
-  if( u.an.payloadSize==0 ){
-    MemSetTypeFlag(u.an.pDest, MEM_Null);
+  if( u.ao.payloadSize==0 ){
+    MemSetTypeFlag(u.ao.pDest, MEM_Null);
     goto op_column_out;
   }
   assert( db->aLimit[SQLITE_LIMIT_LENGTH]>=0 );
-  if( u.an.payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
+  if( u.ao.payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
     goto too_big;
   }
 
-  u.an.nField = u.an.pC->nField;
-  assert( u.an.p2<u.an.nField );
+  u.ao.nField = u.ao.pC->nField;
+  assert( u.ao.p2<u.ao.nField );
 
   /* Read and parse the table header.  Store the results of the parse
   ** into the record header cache fields of the cursor.
   */
-  u.an.aType = u.an.pC->aType;
-  if( u.an.pC->cacheStatus==p->cacheCtr ){
-    u.an.aOffset = u.an.pC->aOffset;
+  u.ao.aType = u.ao.pC->aType;
+  if( u.ao.pC->cacheStatus==p->cacheCtr ){
+    u.ao.aOffset = u.ao.pC->aOffset;
   }else{
-    assert(u.an.aType);
-    u.an.avail = 0;
-    u.an.pC->aOffset = u.an.aOffset = &u.an.aType[u.an.nField];
-    u.an.pC->payloadSize = u.an.payloadSize;
-    u.an.pC->cacheStatus = p->cacheCtr;
+    assert(u.ao.aType);
+    u.ao.avail = 0;
+    u.ao.pC->aOffset = u.ao.aOffset = &u.ao.aType[u.ao.nField];
+    u.ao.pC->payloadSize = u.ao.payloadSize;
+    u.ao.pC->cacheStatus = p->cacheCtr;
 
     /* Figure out how many bytes are in the header */
-    if( u.an.zRec ){
-      u.an.zData = u.an.zRec;
+    if( u.ao.zRec ){
+      u.ao.zData = u.ao.zRec;
     }else{
-      if( u.an.pC->isIndex ){
-        u.an.zData = (char*)sqlite3BtreeKeyFetch(u.an.pCrsr, &u.an.avail);
+      if( u.ao.pC->isIndex ){
+        u.ao.zData = (char*)sqlite3BtreeKeyFetch(u.ao.pCrsr, &u.ao.avail);
       }else{
-        u.an.zData = (char*)sqlite3BtreeDataFetch(u.an.pCrsr, &u.an.avail);
+        u.ao.zData = (char*)sqlite3BtreeDataFetch(u.ao.pCrsr, &u.ao.avail);
       }
       /* If KeyFetch()/DataFetch() managed to get the entire payload,
-      ** save the payload in the u.an.pC->aRow cache.  That will save us from
+      ** save the payload in the u.ao.pC->aRow cache.  That will save us from
       ** having to make additional calls to fetch the content portion of
       ** the record.
       */
-      assert( u.an.avail>=0 );
-      if( u.an.payloadSize <= (u32)u.an.avail ){
-        u.an.zRec = u.an.zData;
-        u.an.pC->aRow = (u8*)u.an.zData;
+      assert( u.ao.avail>=0 );
+      if( u.ao.payloadSize <= (u32)u.ao.avail ){
+        u.ao.zRec = u.ao.zData;
+        u.ao.pC->aRow = (u8*)u.ao.zData;
       }else{
-        u.an.pC->aRow = 0;
+        u.ao.pC->aRow = 0;
       }
     }
     /* The following assert is true in all cases except when
     ** the database file has been corrupted externally.
-    **    assert( u.an.zRec!=0 || u.an.avail>=u.an.payloadSize || u.an.avail>=9 ); */
-    u.an.szHdr = getVarint32((u8*)u.an.zData, u.an.offset);
+    **    assert( u.ao.zRec!=0 || u.ao.avail>=u.ao.payloadSize || u.ao.avail>=9 ); */
+    u.ao.szHdr = getVarint32((u8*)u.ao.zData, u.ao.offset);
 
     /* Make sure a corrupt database has not given us an oversize header.
     ** Do this now to avoid an oversize memory allocation.
@@ -68044,26 +66274,26 @@ case OP_Column: {
     ** 3-byte type for each of the maximum of 32768 columns plus three
     ** extra bytes for the header length itself.  32768*3 + 3 = 98307.
     */
-    if( u.an.offset > 98307 ){
+    if( u.ao.offset > 98307 ){
       rc = SQLITE_CORRUPT_BKPT;
       goto op_column_out;
     }
 
-    /* Compute in u.an.len the number of bytes of data we need to read in order
-    ** to get u.an.nField type values.  u.an.offset is an upper bound on this.  But
-    ** u.an.nField might be significantly less than the true number of columns
-    ** in the table, and in that case, 5*u.an.nField+3 might be smaller than u.an.offset.
-    ** We want to minimize u.an.len in order to limit the size of the memory
-    ** allocation, especially if a corrupt database file has caused u.an.offset
+    /* Compute in u.ao.len the number of bytes of data we need to read in order
+    ** to get u.ao.nField type values.  u.ao.offset is an upper bound on this.  But
+    ** u.ao.nField might be significantly less than the true number of columns
+    ** in the table, and in that case, 5*u.ao.nField+3 might be smaller than u.ao.offset.
+    ** We want to minimize u.ao.len in order to limit the size of the memory
+    ** allocation, especially if a corrupt database file has caused u.ao.offset
     ** to be oversized. Offset is limited to 98307 above.  But 98307 might
     ** still exceed Robson memory allocation limits on some configurations.
-    ** On systems that cannot tolerate large memory allocations, u.an.nField*5+3
-    ** will likely be much smaller since u.an.nField will likely be less than
+    ** On systems that cannot tolerate large memory allocations, u.ao.nField*5+3
+    ** will likely be much smaller since u.ao.nField will likely be less than
     ** 20 or so.  This insures that Robson memory allocation limits are
     ** not exceeded even for corrupt database files.
     */
-    u.an.len = u.an.nField*5 + 3;
-    if( u.an.len > (int)u.an.offset ) u.an.len = (int)u.an.offset;
+    u.ao.len = u.ao.nField*5 + 3;
+    if( u.ao.len > (int)u.ao.offset ) u.ao.len = (int)u.ao.offset;
 
     /* The KeyFetch() or DataFetch() above are fast and will get the entire
     ** record header in most cases.  But they will fail to get the complete
@@ -68071,51 +66301,51 @@ case OP_Column: {
     ** in the B-Tree.  When that happens, use sqlite3VdbeMemFromBtree() to
     ** acquire the complete header text.
     */
-    if( !u.an.zRec && u.an.avail<u.an.len ){
-      u.an.sMem.flags = 0;
-      u.an.sMem.db = 0;
-      rc = sqlite3VdbeMemFromBtree(u.an.pCrsr, 0, u.an.len, u.an.pC->isIndex, &u.an.sMem);
+    if( !u.ao.zRec && u.ao.avail<u.ao.len ){
+      u.ao.sMem.flags = 0;
+      u.ao.sMem.db = 0;
+      rc = sqlite3VdbeMemFromBtree(u.ao.pCrsr, 0, u.ao.len, u.ao.pC->isIndex, &u.ao.sMem);
       if( rc!=SQLITE_OK ){
         goto op_column_out;
       }
-      u.an.zData = u.an.sMem.z;
+      u.ao.zData = u.ao.sMem.z;
     }
-    u.an.zEndHdr = (u8 *)&u.an.zData[u.an.len];
-    u.an.zIdx = (u8 *)&u.an.zData[u.an.szHdr];
+    u.ao.zEndHdr = (u8 *)&u.ao.zData[u.ao.len];
+    u.ao.zIdx = (u8 *)&u.ao.zData[u.ao.szHdr];
 
-    /* Scan the header and use it to fill in the u.an.aType[] and u.an.aOffset[]
-    ** arrays.  u.an.aType[u.an.i] will contain the type integer for the u.an.i-th
-    ** column and u.an.aOffset[u.an.i] will contain the u.an.offset from the beginning
-    ** of the record to the start of the data for the u.an.i-th column
+    /* Scan the header and use it to fill in the u.ao.aType[] and u.ao.aOffset[]
+    ** arrays.  u.ao.aType[u.ao.i] will contain the type integer for the u.ao.i-th
+    ** column and u.ao.aOffset[u.ao.i] will contain the u.ao.offset from the beginning
+    ** of the record to the start of the data for the u.ao.i-th column
     */
-    for(u.an.i=0; u.an.i<u.an.nField; u.an.i++){
-      if( u.an.zIdx<u.an.zEndHdr ){
-        u.an.aOffset[u.an.i] = u.an.offset;
-        if( u.an.zIdx[0]<0x80 ){
-          u.an.t = u.an.zIdx[0];
-          u.an.zIdx++;
+    for(u.ao.i=0; u.ao.i<u.ao.nField; u.ao.i++){
+      if( u.ao.zIdx<u.ao.zEndHdr ){
+        u.ao.aOffset[u.ao.i] = u.ao.offset;
+        if( u.ao.zIdx[0]<0x80 ){
+          u.ao.t = u.ao.zIdx[0];
+          u.ao.zIdx++;
         }else{
-          u.an.zIdx += sqlite3GetVarint32(u.an.zIdx, &u.an.t);
+          u.ao.zIdx += sqlite3GetVarint32(u.ao.zIdx, &u.ao.t);
         }
-        u.an.aType[u.an.i] = u.an.t;
-        u.an.szField = sqlite3VdbeSerialTypeLen(u.an.t);
-        u.an.offset += u.an.szField;
-        if( u.an.offset<u.an.szField ){  /* True if u.an.offset overflows */
-          u.an.zIdx = &u.an.zEndHdr[1];  /* Forces SQLITE_CORRUPT return below */
+        u.ao.aType[u.ao.i] = u.ao.t;
+        u.ao.szField = sqlite3VdbeSerialTypeLen(u.ao.t);
+        u.ao.offset += u.ao.szField;
+        if( u.ao.offset<u.ao.szField ){  /* True if u.ao.offset overflows */
+          u.ao.zIdx = &u.ao.zEndHdr[1];  /* Forces SQLITE_CORRUPT return below */
           break;
         }
       }else{
-        /* If u.an.i is less that u.an.nField, then there are fewer fields in this
+        /* If u.ao.i is less that u.ao.nField, then there are fewer fields in this
         ** record than SetNumColumns indicated there are columns in the
-        ** table. Set the u.an.offset for any extra columns not present in
+        ** table. Set the u.ao.offset for any extra columns not present in
         ** the record to 0. This tells code below to store the default value
         ** for the column instead of deserializing a value from the record.
         */
-        u.an.aOffset[u.an.i] = 0;
+        u.ao.aOffset[u.ao.i] = 0;
       }
     }
-    sqlite3VdbeMemRelease(&u.an.sMem);
-    u.an.sMem.flags = MEM_Null;
+    sqlite3VdbeMemRelease(&u.ao.sMem);
+    u.ao.sMem.flags = MEM_Null;
 
     /* If we have read more header data than was contained in the header,
     ** or if the end of the last field appears to be past the end of the
@@ -68123,78 +66353,78 @@ case OP_Column: {
     ** of the record (when all fields present), then we must be dealing
     ** with a corrupt database.
     */
-    if( (u.an.zIdx > u.an.zEndHdr) || (u.an.offset > u.an.payloadSize)
-         || (u.an.zIdx==u.an.zEndHdr && u.an.offset!=u.an.payloadSize) ){
+    if( (u.ao.zIdx > u.ao.zEndHdr) || (u.ao.offset > u.ao.payloadSize)
+         || (u.ao.zIdx==u.ao.zEndHdr && u.ao.offset!=u.ao.payloadSize) ){
       rc = SQLITE_CORRUPT_BKPT;
       goto op_column_out;
     }
   }
 
-  /* Get the column information. If u.an.aOffset[u.an.p2] is non-zero, then
-  ** deserialize the value from the record. If u.an.aOffset[u.an.p2] is zero,
+  /* Get the column information. If u.ao.aOffset[u.ao.p2] is non-zero, then
+  ** deserialize the value from the record. If u.ao.aOffset[u.ao.p2] is zero,
   ** then there are not enough fields in the record to satisfy the
   ** request.  In this case, set the value NULL or to P4 if P4 is
   ** a pointer to a Mem object.
   */
-  if( u.an.aOffset[u.an.p2] ){
+  if( u.ao.aOffset[u.ao.p2] ){
     assert( rc==SQLITE_OK );
-    if( u.an.zRec ){
+    if( u.ao.zRec ){
       /* This is the common case where the whole row fits on a single page */
-      VdbeMemRelease(u.an.pDest);
-      sqlite3VdbeSerialGet((u8 *)&u.an.zRec[u.an.aOffset[u.an.p2]], u.an.aType[u.an.p2], u.an.pDest);
+      VdbeMemRelease(u.ao.pDest);
+      sqlite3VdbeSerialGet((u8 *)&u.ao.zRec[u.ao.aOffset[u.ao.p2]], u.ao.aType[u.ao.p2], u.ao.pDest);
     }else{
       /* This branch happens only when the row overflows onto multiple pages */
-      u.an.t = u.an.aType[u.an.p2];
+      u.ao.t = u.ao.aType[u.ao.p2];
       if( (pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0
-       && ((u.an.t>=12 && (u.an.t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0)
+       && ((u.ao.t>=12 && (u.ao.t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0)
       ){
         /* Content is irrelevant for the typeof() function and for
         ** the length(X) function if X is a blob.  So we might as well use
         ** bogus content rather than reading content from disk.  NULL works
-        ** for text and blob and whatever is in the u.an.payloadSize64 variable
+        ** for text and blob and whatever is in the u.ao.payloadSize64 variable
         ** will work for everything else. */
-        u.an.zData = u.an.t<12 ? (char*)&u.an.payloadSize64 : 0;
+        u.ao.zData = u.ao.t<12 ? (char*)&u.ao.payloadSize64 : 0;
       }else{
-        u.an.len = sqlite3VdbeSerialTypeLen(u.an.t);
-        sqlite3VdbeMemMove(&u.an.sMem, u.an.pDest);
-        rc = sqlite3VdbeMemFromBtree(u.an.pCrsr, u.an.aOffset[u.an.p2], u.an.len,  u.an.pC->isIndex,
-                                     &u.an.sMem);
+        u.ao.len = sqlite3VdbeSerialTypeLen(u.ao.t);
+        sqlite3VdbeMemMove(&u.ao.sMem, u.ao.pDest);
+        rc = sqlite3VdbeMemFromBtree(u.ao.pCrsr, u.ao.aOffset[u.ao.p2], u.ao.len,  u.ao.pC->isIndex,
+                                     &u.ao.sMem);
         if( rc!=SQLITE_OK ){
           goto op_column_out;
         }
-        u.an.zData = u.an.sMem.z;
+        u.ao.zData = u.ao.sMem.z;
       }
-      sqlite3VdbeSerialGet((u8*)u.an.zData, u.an.t, u.an.pDest);
+      sqlite3VdbeSerialGet((u8*)u.ao.zData, u.ao.t, u.ao.pDest);
     }
-    u.an.pDest->enc = encoding;
+    u.ao.pDest->enc = encoding;
   }else{
     if( pOp->p4type==P4_MEM ){
-      sqlite3VdbeMemShallowCopy(u.an.pDest, pOp->p4.pMem, MEM_Static);
+      sqlite3VdbeMemShallowCopy(u.ao.pDest, pOp->p4.pMem, MEM_Static);
     }else{
-      MemSetTypeFlag(u.an.pDest, MEM_Null);
+      MemSetTypeFlag(u.ao.pDest, MEM_Null);
     }
   }
 
   /* If we dynamically allocated space to hold the data (in the
   ** sqlite3VdbeMemFromBtree() call above) then transfer control of that
-  ** dynamically allocated space over to the u.an.pDest structure.
+  ** dynamically allocated space over to the u.ao.pDest structure.
   ** This prevents a memory copy.
   */
-  if( u.an.sMem.zMalloc ){
-    assert( u.an.sMem.z==u.an.sMem.zMalloc );
-    assert( !(u.an.pDest->flags & MEM_Dyn) );
-    assert( !(u.an.pDest->flags & (MEM_Blob|MEM_Str)) || u.an.pDest->z==u.an.sMem.z );
-    u.an.pDest->flags &= ~(MEM_Ephem|MEM_Static);
-    u.an.pDest->flags |= MEM_Term;
-    u.an.pDest->z = u.an.sMem.z;
-    u.an.pDest->zMalloc = u.an.sMem.zMalloc;
+  if( u.ao.sMem.zMalloc ){
+    assert( u.ao.sMem.z==u.ao.sMem.zMalloc );
+    assert( !(u.ao.pDest->flags & MEM_Dyn) );
+    assert( !(u.ao.pDest->flags & (MEM_Blob|MEM_Str)) || u.ao.pDest->z==u.ao.sMem.z );
+    u.ao.pDest->flags &= ~(MEM_Ephem|MEM_Static);
+    u.ao.pDest->flags |= MEM_Term;
+    u.ao.pDest->z = u.ao.sMem.z;
+    u.ao.pDest->zMalloc = u.ao.sMem.zMalloc;
   }
 
-  rc = sqlite3VdbeMemMakeWriteable(u.an.pDest);
+  rc = sqlite3VdbeMemMakeWriteable(u.ao.pDest);
 
 op_column_out:
-  UPDATE_MAX_BLOBSIZE(u.an.pDest);
-  REGISTER_TRACE(pOp->p3, u.an.pDest);
+  UPDATE_MAX_BLOBSIZE(u.ao.pDest);
+  REGISTER_TRACE(pOp->p3, u.ao.pDest);
   break;
 }
 
@@ -68207,20 +66437,20 @@ op_column_out:
 ** memory cell in the range.
 */
 case OP_Affinity: {
-#if 0  /* local variables moved into u.ao */
+#if 0  /* local variables moved into u.ap */
   const char *zAffinity;   /* The affinity to be applied */
   char cAff;               /* A single character of affinity */
-#endif /* local variables moved into u.ao */
+#endif /* local variables moved into u.ap */
 
-  u.ao.zAffinity = pOp->p4.z;
-  assert( u.ao.zAffinity!=0 );
-  assert( u.ao.zAffinity[pOp->p2]==0 );
+  u.ap.zAffinity = pOp->p4.z;
+  assert( u.ap.zAffinity!=0 );
+  assert( u.ap.zAffinity[pOp->p2]==0 );
   pIn1 = &aMem[pOp->p1];
-  while( (u.ao.cAff = *(u.ao.zAffinity++))!=0 ){
+  while( (u.ap.cAff = *(u.ap.zAffinity++))!=0 ){
     assert( pIn1 <= &p->aMem[p->nMem] );
     assert( memIsValid(pIn1) );
     ExpandBlob(pIn1);
-    applyAffinity(pIn1, u.ao.cAff, encoding);
+    applyAffinity(pIn1, u.ap.cAff, encoding);
     pIn1++;
   }
   break;
@@ -68242,7 +66472,7 @@ case OP_Affinity: {
 ** If P4 is NULL then all index fields have the affinity NONE.
 */
 case OP_MakeRecord: {
-#if 0  /* local variables moved into u.ap */
+#if 0  /* local variables moved into u.aq */
   u8 *zNewRecord;        /* A buffer to hold the data for the new record */
   Mem *pRec;             /* The new record */
   u64 nData;             /* Number of bytes of data space */
@@ -68258,7 +66488,7 @@ case OP_MakeRecord: {
   int file_format;       /* File format to use for encoding */
   int i;                 /* Space used in zNewRecord[] */
   int len;               /* Length of a field */
-#endif /* local variables moved into u.ap */
+#endif /* local variables moved into u.aq */
 
   /* Assuming the record contains N fields, the record format looks
   ** like this:
@@ -68275,16 +66505,16 @@ case OP_MakeRecord: {
   ** hdr-size field is also a varint which is the offset from the beginning
   ** of the record to data0.
   */
-  u.ap.nData = 0;         /* Number of bytes of data space */
-  u.ap.nHdr = 0;          /* Number of bytes of header space */
-  u.ap.nZero = 0;         /* Number of zero bytes at the end of the record */
-  u.ap.nField = pOp->p1;
-  u.ap.zAffinity = pOp->p4.z;
-  assert( u.ap.nField>0 && pOp->p2>0 && pOp->p2+u.ap.nField<=p->nMem+1 );
-  u.ap.pData0 = &aMem[u.ap.nField];
-  u.ap.nField = pOp->p2;
-  u.ap.pLast = &u.ap.pData0[u.ap.nField-1];
-  u.ap.file_format = p->minWriteFileFormat;
+  u.aq.nData = 0;         /* Number of bytes of data space */
+  u.aq.nHdr = 0;          /* Number of bytes of header space */
+  u.aq.nZero = 0;         /* Number of zero bytes at the end of the record */
+  u.aq.nField = pOp->p1;
+  u.aq.zAffinity = pOp->p4.z;
+  assert( u.aq.nField>0 && pOp->p2>0 && pOp->p2+u.aq.nField<=p->nMem+1 );
+  u.aq.pData0 = &aMem[u.aq.nField];
+  u.aq.nField = pOp->p2;
+  u.aq.pLast = &u.aq.pData0[u.aq.nField-1];
+  u.aq.file_format = p->minWriteFileFormat;
 
   /* Identify the output register */
   assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 );
@@ -68294,34 +66524,34 @@ case OP_MakeRecord: {
   /* Loop through the elements that will make up the record to figure
   ** out how much space is required for the new record.
   */
-  for(u.ap.pRec=u.ap.pData0; u.ap.pRec<=u.ap.pLast; u.ap.pRec++){
-    assert( memIsValid(u.ap.pRec) );
-    if( u.ap.zAffinity ){
-      applyAffinity(u.ap.pRec, u.ap.zAffinity[u.ap.pRec-u.ap.pData0], encoding);
+  for(u.aq.pRec=u.aq.pData0; u.aq.pRec<=u.aq.pLast; u.aq.pRec++){
+    assert( memIsValid(u.aq.pRec) );
+    if( u.aq.zAffinity ){
+      applyAffinity(u.aq.pRec, u.aq.zAffinity[u.aq.pRec-u.aq.pData0], encoding);
     }
-    if( u.ap.pRec->flags&MEM_Zero && u.ap.pRec->n>0 ){
-      sqlite3VdbeMemExpandBlob(u.ap.pRec);
+    if( u.aq.pRec->flags&MEM_Zero && u.aq.pRec->n>0 ){
+      sqlite3VdbeMemExpandBlob(u.aq.pRec);
     }
-    u.ap.serial_type = sqlite3VdbeSerialType(u.ap.pRec, u.ap.file_format);
-    u.ap.len = sqlite3VdbeSerialTypeLen(u.ap.serial_type);
-    u.ap.nData += u.ap.len;
-    u.ap.nHdr += sqlite3VarintLen(u.ap.serial_type);
-    if( u.ap.pRec->flags & MEM_Zero ){
+    u.aq.serial_type = sqlite3VdbeSerialType(u.aq.pRec, u.aq.file_format);
+    u.aq.len = sqlite3VdbeSerialTypeLen(u.aq.serial_type);
+    u.aq.nData += u.aq.len;
+    u.aq.nHdr += sqlite3VarintLen(u.aq.serial_type);
+    if( u.aq.pRec->flags & MEM_Zero ){
       /* Only pure zero-filled BLOBs can be input to this Opcode.
       ** We do not allow blobs with a prefix and a zero-filled tail. */
-      u.ap.nZero += u.ap.pRec->u.nZero;
-    }else if( u.ap.len ){
-      u.ap.nZero = 0;
+      u.aq.nZero += u.aq.pRec->u.nZero;
+    }else if( u.aq.len ){
+      u.aq.nZero = 0;
     }
   }
 
   /* Add the initial header varint and total the size */
-  u.ap.nHdr += u.ap.nVarint = sqlite3VarintLen(u.ap.nHdr);
-  if( u.ap.nVarint<sqlite3VarintLen(u.ap.nHdr) ){
-    u.ap.nHdr++;
+  u.aq.nHdr += u.aq.nVarint = sqlite3VarintLen(u.aq.nHdr);
+  if( u.aq.nVarint<sqlite3VarintLen(u.aq.nHdr) ){
+    u.aq.nHdr++;
   }
-  u.ap.nByte = u.ap.nHdr+u.ap.nData-u.ap.nZero;
-  if( u.ap.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+  u.aq.nByte = u.aq.nHdr+u.aq.nData-u.aq.nZero;
+  if( u.aq.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
     goto too_big;
   }
 
@@ -68330,28 +66560,28 @@ case OP_MakeRecord: {
   ** be one of the input registers (because the following call to
   ** sqlite3VdbeMemGrow() could clobber the value before it is used).
   */
-  if( sqlite3VdbeMemGrow(pOut, (int)u.ap.nByte, 0) ){
+  if( sqlite3VdbeMemGrow(pOut, (int)u.aq.nByte, 0) ){
     goto no_mem;
   }
-  u.ap.zNewRecord = (u8 *)pOut->z;
+  u.aq.zNewRecord = (u8 *)pOut->z;
 
   /* Write the record */
-  u.ap.i = putVarint32(u.ap.zNewRecord, u.ap.nHdr);
-  for(u.ap.pRec=u.ap.pData0; u.ap.pRec<=u.ap.pLast; u.ap.pRec++){
-    u.ap.serial_type = sqlite3VdbeSerialType(u.ap.pRec, u.ap.file_format);
-    u.ap.i += putVarint32(&u.ap.zNewRecord[u.ap.i], u.ap.serial_type);      /* serial type */
+  u.aq.i = putVarint32(u.aq.zNewRecord, u.aq.nHdr);
+  for(u.aq.pRec=u.aq.pData0; u.aq.pRec<=u.aq.pLast; u.aq.pRec++){
+    u.aq.serial_type = sqlite3VdbeSerialType(u.aq.pRec, u.aq.file_format);
+    u.aq.i += putVarint32(&u.aq.zNewRecord[u.aq.i], u.aq.serial_type);      /* serial type */
   }
-  for(u.ap.pRec=u.ap.pData0; u.ap.pRec<=u.ap.pLast; u.ap.pRec++){  /* serial data */
-    u.ap.i += sqlite3VdbeSerialPut(&u.ap.zNewRecord[u.ap.i], (int)(u.ap.nByte-u.ap.i), u.ap.pRec,u.ap.file_format);
+  for(u.aq.pRec=u.aq.pData0; u.aq.pRec<=u.aq.pLast; u.aq.pRec++){  /* serial data */
+    u.aq.i += sqlite3VdbeSerialPut(&u.aq.zNewRecord[u.aq.i], (int)(u.aq.nByte-u.aq.i), u.aq.pRec,u.aq.file_format);
   }
-  assert( u.ap.i==u.ap.nByte );
+  assert( u.aq.i==u.aq.nByte );
 
   assert( pOp->p3>0 && pOp->p3<=p->nMem );
-  pOut->n = (int)u.ap.nByte;
+  pOut->n = (int)u.aq.nByte;
   pOut->flags = MEM_Blob | MEM_Dyn;
   pOut->xDel = 0;
-  if( u.ap.nZero ){
-    pOut->u.nZero = u.ap.nZero;
+  if( u.aq.nZero ){
+    pOut->u.nZero = u.aq.nZero;
     pOut->flags |= MEM_Zero;
   }
   pOut->enc = SQLITE_UTF8;  /* In case the blob is ever converted to text */
@@ -68367,18 +66597,18 @@ case OP_MakeRecord: {
 */
 #ifndef SQLITE_OMIT_BTREECOUNT
 case OP_Count: {         /* out2-prerelease */
-#if 0  /* local variables moved into u.aq */
+#if 0  /* local variables moved into u.ar */
   i64 nEntry;
   BtCursor *pCrsr;
-#endif /* local variables moved into u.aq */
+#endif /* local variables moved into u.ar */
 
-  u.aq.pCrsr = p->apCsr[pOp->p1]->pCursor;
-  if( ALWAYS(u.aq.pCrsr) ){
-    rc = sqlite3BtreeCount(u.aq.pCrsr, &u.aq.nEntry);
+  u.ar.pCrsr = p->apCsr[pOp->p1]->pCursor;
+  if( ALWAYS(u.ar.pCrsr) ){
+    rc = sqlite3BtreeCount(u.ar.pCrsr, &u.ar.nEntry);
   }else{
-    u.aq.nEntry = 0;
+    u.ar.nEntry = 0;
   }
-  pOut->u.i = u.aq.nEntry;
+  pOut->u.i = u.ar.nEntry;
   break;
 }
 #endif
@@ -68390,7 +66620,7 @@ case OP_Count: {         /* out2-prerelease */
 ** existing savepoint, P1==1, or to rollback an existing savepoint P1==2.
 */
 case OP_Savepoint: {
-#if 0  /* local variables moved into u.ar */
+#if 0  /* local variables moved into u.as */
   int p1;                         /* Value of P1 operand */
   char *zName;                    /* Name of savepoint */
   int nName;
@@ -68399,20 +66629,20 @@ case OP_Savepoint: {
   Savepoint *pTmp;
   int iSavepoint;
   int ii;
-#endif /* local variables moved into u.ar */
+#endif /* local variables moved into u.as */
 
-  u.ar.p1 = pOp->p1;
-  u.ar.zName = pOp->p4.z;
+  u.as.p1 = pOp->p1;
+  u.as.zName = pOp->p4.z;
 
-  /* Assert that the u.ar.p1 parameter is valid. Also that if there is no open
+  /* Assert that the u.as.p1 parameter is valid. Also that if there is no open
   ** transaction, then there cannot be any savepoints.
   */
   assert( db->pSavepoint==0 || db->autoCommit==0 );
-  assert( u.ar.p1==SAVEPOINT_BEGIN||u.ar.p1==SAVEPOINT_RELEASE||u.ar.p1==SAVEPOINT_ROLLBACK );
+  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) );
 
-  if( u.ar.p1==SAVEPOINT_BEGIN ){
+  if( u.as.p1==SAVEPOINT_BEGIN ){
     if( db->writeVdbeCnt>0 ){
       /* A new savepoint cannot be created if there are active write
       ** statements (i.e. open read/write incremental blob handles).
@@ -68421,7 +66651,7 @@ case OP_Savepoint: {
         "SQL statements in progress");
       rc = SQLITE_BUSY;
     }else{
-      u.ar.nName = sqlite3Strlen30(u.ar.zName);
+      u.as.nName = sqlite3Strlen30(u.as.zName);
 
 #ifndef SQLITE_OMIT_VIRTUALTABLE
       /* This call is Ok even if this savepoint is actually a transaction
@@ -68435,10 +66665,10 @@ case OP_Savepoint: {
 #endif
 
       /* Create a new savepoint structure. */
-      u.ar.pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+u.ar.nName+1);
-      if( u.ar.pNew ){
-        u.ar.pNew->zName = (char *)&u.ar.pNew[1];
-        memcpy(u.ar.pNew->zName, u.ar.zName, u.ar.nName+1);
+      u.as.pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+u.as.nName+1);
+      if( u.as.pNew ){
+        u.as.pNew->zName = (char *)&u.as.pNew[1];
+        memcpy(u.as.pNew->zName, u.as.zName, u.as.nName+1);
 
         /* If there is no open transaction, then mark this as a special
         ** "transaction savepoint". */
@@ -68450,27 +66680,27 @@ case OP_Savepoint: {
         }
 
         /* Link the new savepoint into the database handle's list. */
-        u.ar.pNew->pNext = db->pSavepoint;
-        db->pSavepoint = u.ar.pNew;
-        u.ar.pNew->nDeferredCons = db->nDeferredCons;
+        u.as.pNew->pNext = db->pSavepoint;
+        db->pSavepoint = u.as.pNew;
+        u.as.pNew->nDeferredCons = db->nDeferredCons;
       }
     }
   }else{
-    u.ar.iSavepoint = 0;
+    u.as.iSavepoint = 0;
 
     /* Find the named savepoint. If there is no such savepoint, then an
     ** an error is returned to the user.  */
     for(
-      u.ar.pSavepoint = db->pSavepoint;
-      u.ar.pSavepoint && sqlite3StrICmp(u.ar.pSavepoint->zName, u.ar.zName);
-      u.ar.pSavepoint = u.ar.pSavepoint->pNext
+      u.as.pSavepoint = db->pSavepoint;
+      u.as.pSavepoint && sqlite3StrICmp(u.as.pSavepoint->zName, u.as.zName);
+      u.as.pSavepoint = u.as.pSavepoint->pNext
     ){
-      u.ar.iSavepoint++;
+      u.as.iSavepoint++;
     }
-    if( !u.ar.pSavepoint ){
-      sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", u.ar.zName);
+    if( !u.as.pSavepoint ){
+      sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", u.as.zName);
       rc = SQLITE_ERROR;
-    }else if( db->writeVdbeCnt>0 && u.ar.p1==SAVEPOINT_RELEASE ){
+    }else if( db->writeVdbeCnt>0 && u.as.p1==SAVEPOINT_RELEASE ){
       /* It is not possible to release (commit) a savepoint if there are
       ** active write statements.
       */
@@ -68484,8 +66714,8 @@ case OP_Savepoint: {
       ** and this is a RELEASE command, then the current transaction
       ** is committed.
       */
-      int isTransaction = u.ar.pSavepoint->pNext==0 && db->isTransactionSavepoint;
-      if( isTransaction && u.ar.p1==SAVEPOINT_RELEASE ){
+      int isTransaction = u.as.pSavepoint->pNext==0 && db->isTransactionSavepoint;
+      if( isTransaction && u.as.p1==SAVEPOINT_RELEASE ){
         if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
           goto vdbe_return;
         }
@@ -68499,19 +66729,19 @@ case OP_Savepoint: {
         db->isTransactionSavepoint = 0;
         rc = p->rc;
       }else{
-        u.ar.iSavepoint = db->nSavepoint - u.ar.iSavepoint - 1;
-        if( u.ar.p1==SAVEPOINT_ROLLBACK ){
-          for(u.ar.ii=0; u.ar.ii<db->nDb; u.ar.ii++){
-            sqlite3BtreeTripAllCursors(db->aDb[u.ar.ii].pBt, SQLITE_ABORT);
+        u.as.iSavepoint = db->nSavepoint - u.as.iSavepoint - 1;
+        if( u.as.p1==SAVEPOINT_ROLLBACK ){
+          for(u.as.ii=0; u.as.ii<db->nDb; u.as.ii++){
+            sqlite3BtreeTripAllCursors(db->aDb[u.as.ii].pBt, SQLITE_ABORT);
           }
         }
-        for(u.ar.ii=0; u.ar.ii<db->nDb; u.ar.ii++){
-          rc = sqlite3BtreeSavepoint(db->aDb[u.ar.ii].pBt, u.ar.p1, u.ar.iSavepoint);
+        for(u.as.ii=0; u.as.ii<db->nDb; u.as.ii++){
+          rc = sqlite3BtreeSavepoint(db->aDb[u.as.ii].pBt, u.as.p1, u.as.iSavepoint);
           if( rc!=SQLITE_OK ){
             goto abort_due_to_error;
           }
         }
-        if( u.ar.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
+        if( u.as.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
           sqlite3ExpirePreparedStatements(db);
           sqlite3ResetAllSchemasOfConnection(db);
           db->flags = (db->flags | SQLITE_InternChanges);
@@ -68520,10 +66750,10 @@ case OP_Savepoint: {
 
       /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all
       ** savepoints nested inside of the savepoint being operated on. */
-      while( db->pSavepoint!=u.ar.pSavepoint ){
-        u.ar.pTmp = db->pSavepoint;
-        db->pSavepoint = u.ar.pTmp->pNext;
-        sqlite3DbFree(db, u.ar.pTmp);
+      while( db->pSavepoint!=u.as.pSavepoint ){
+        u.as.pTmp = db->pSavepoint;
+        db->pSavepoint = u.as.pTmp->pNext;
+        sqlite3DbFree(db, u.as.pTmp);
         db->nSavepoint--;
       }
 
@@ -68531,19 +66761,19 @@ case OP_Savepoint: {
       ** too. If it is a ROLLBACK TO, then set the number of deferred
       ** constraint violations present in the database to the value stored
       ** when the savepoint was created.  */
-      if( u.ar.p1==SAVEPOINT_RELEASE ){
-        assert( u.ar.pSavepoint==db->pSavepoint );
-        db->pSavepoint = u.ar.pSavepoint->pNext;
-        sqlite3DbFree(db, u.ar.pSavepoint);
+      if( u.as.p1==SAVEPOINT_RELEASE ){
+        assert( u.as.pSavepoint==db->pSavepoint );
+        db->pSavepoint = u.as.pSavepoint->pNext;
+        sqlite3DbFree(db, u.as.pSavepoint);
         if( !isTransaction ){
           db->nSavepoint--;
         }
       }else{
-        db->nDeferredCons = u.ar.pSavepoint->nDeferredCons;
+        db->nDeferredCons = u.as.pSavepoint->nDeferredCons;
       }
 
       if( !isTransaction ){
-        rc = sqlite3VtabSavepoint(db, u.ar.p1, u.ar.iSavepoint);
+        rc = sqlite3VtabSavepoint(db, u.as.p1, u.as.iSavepoint);
         if( rc!=SQLITE_OK ) goto abort_due_to_error;
       }
     }
@@ -68562,21 +66792,21 @@ case OP_Savepoint: {
 ** This instruction causes the VM to halt.
 */
 case OP_AutoCommit: {
-#if 0  /* local variables moved into u.as */
+#if 0  /* local variables moved into u.at */
   int desiredAutoCommit;
   int iRollback;
   int turnOnAC;
-#endif /* local variables moved into u.as */
+#endif /* local variables moved into u.at */
 
-  u.as.desiredAutoCommit = pOp->p1;
-  u.as.iRollback = pOp->p2;
-  u.as.turnOnAC = u.as.desiredAutoCommit && !db->autoCommit;
-  assert( u.as.desiredAutoCommit==1 || u.as.desiredAutoCommit==0 );
-  assert( u.as.desiredAutoCommit==1 || u.as.iRollback==0 );
+  u.at.desiredAutoCommit = pOp->p1;
+  u.at.iRollback = pOp->p2;
+  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 */
 
 #if 0
-  if( u.as.turnOnAC && u.as.iRollback && db->activeVdbeCnt>1 ){
+  if( u.at.turnOnAC && u.at.iRollback && db->activeVdbeCnt>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.
@@ -68586,25 +66816,25 @@ case OP_AutoCommit: {
     rc = SQLITE_BUSY;
   }else
 #endif
-  if( u.as.turnOnAC && !u.as.iRollback && db->writeVdbeCnt>0 ){
+  if( u.at.turnOnAC && !u.at.iRollback && db->writeVdbeCnt>0 ){
     /* If this instruction implements a COMMIT and other VMs are writing
     ** return an error indicating that the other VMs must complete first.
     */
     sqlite3SetString(&p->zErrMsg, db, "cannot commit transaction - "
         "SQL statements in progress");
     rc = SQLITE_BUSY;
-  }else if( u.as.desiredAutoCommit!=db->autoCommit ){
-    if( u.as.iRollback ){
-      assert( u.as.desiredAutoCommit==1 );
+  }else if( u.at.desiredAutoCommit!=db->autoCommit ){
+    if( u.at.iRollback ){
+      assert( u.at.desiredAutoCommit==1 );
       sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
       db->autoCommit = 1;
     }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
       goto vdbe_return;
     }else{
-      db->autoCommit = (u8)u.as.desiredAutoCommit;
+      db->autoCommit = (u8)u.at.desiredAutoCommit;
       if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
         p->pc = pc;
-        db->autoCommit = (u8)(1-u.as.desiredAutoCommit);
+        db->autoCommit = (u8)(1-u.at.desiredAutoCommit);
         p->rc = rc = SQLITE_BUSY;
         goto vdbe_return;
       }
@@ -68619,8 +66849,8 @@ case OP_AutoCommit: {
     goto vdbe_return;
   }else{
     sqlite3SetString(&p->zErrMsg, db,
-        (!u.as.desiredAutoCommit)?"cannot start a transaction within a transaction":(
-        (u.as.iRollback)?"cannot rollback - no transaction is active":
+        (!u.at.desiredAutoCommit)?"cannot start a transaction within a transaction":(
+        (u.at.iRollback)?"cannot rollback - no transaction is active":
                    "cannot commit - no transaction is active"));
 
     rc = SQLITE_ERROR;
@@ -68660,16 +66890,16 @@ case OP_AutoCommit: {
 ** If P2 is zero, then a read-lock is obtained on the database file.
 */
 case OP_Transaction: {
-#if 0  /* local variables moved into u.at */
+#if 0  /* local variables moved into u.au */
   Btree *pBt;
-#endif /* local variables moved into u.at */
+#endif /* local variables moved into u.au */
 
   assert( pOp->p1>=0 && pOp->p1<db->nDb );
   assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
-  u.at.pBt = db->aDb[pOp->p1].pBt;
+  u.au.pBt = db->aDb[pOp->p1].pBt;
 
-  if( u.at.pBt ){
-    rc = sqlite3BtreeBeginTrans(u.at.pBt, pOp->p2);
+  if( u.au.pBt ){
+    rc = sqlite3BtreeBeginTrans(u.au.pBt, pOp->p2);
     if( rc==SQLITE_BUSY ){
       p->pc = pc;
       p->rc = rc = SQLITE_BUSY;
@@ -68682,7 +66912,7 @@ case OP_Transaction: {
     if( pOp->p2 && p->usesStmtJournal
      && (db->autoCommit==0 || db->activeVdbeCnt>1)
     ){
-      assert( sqlite3BtreeIsInTrans(u.at.pBt) );
+      assert( sqlite3BtreeIsInTrans(u.au.pBt) );
       if( p->iStatement==0 ){
         assert( db->nStatement>=0 && db->nSavepoint>=0 );
         db->nStatement++;
@@ -68691,7 +66921,7 @@ case OP_Transaction: {
 
       rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement-1);
       if( rc==SQLITE_OK ){
-        rc = sqlite3BtreeBeginStmt(u.at.pBt, p->iStatement);
+        rc = sqlite3BtreeBeginStmt(u.au.pBt, p->iStatement);
       }
 
       /* Store the current value of the database handles deferred constraint
@@ -68716,21 +66946,21 @@ case OP_Transaction: {
 ** executing this instruction.
 */
 case OP_ReadCookie: {               /* out2-prerelease */
-#if 0  /* local variables moved into u.au */
+#if 0  /* local variables moved into u.av */
   int iMeta;
   int iDb;
   int iCookie;
-#endif /* local variables moved into u.au */
+#endif /* local variables moved into u.av */
 
-  u.au.iDb = pOp->p1;
-  u.au.iCookie = pOp->p3;
+  u.av.iDb = pOp->p1;
+  u.av.iCookie = pOp->p3;
   assert( pOp->p3<SQLITE_N_BTREE_META );
-  assert( u.au.iDb>=0 && u.au.iDb<db->nDb );
-  assert( db->aDb[u.au.iDb].pBt!=0 );
-  assert( (p->btreeMask & (((yDbMask)1)<<u.au.iDb))!=0 );
+  assert( u.av.iDb>=0 && u.av.iDb<db->nDb );
+  assert( db->aDb[u.av.iDb].pBt!=0 );
+  assert( (p->btreeMask & (((yDbMask)1)<<u.av.iDb))!=0 );
 
-  sqlite3BtreeGetMeta(db->aDb[u.au.iDb].pBt, u.au.iCookie, (u32 *)&u.au.iMeta);
-  pOut->u.i = u.au.iMeta;
+  sqlite3BtreeGetMeta(db->aDb[u.av.iDb].pBt, u.av.iCookie, (u32 *)&u.av.iMeta);
+  pOut->u.i = u.av.iMeta;
   break;
 }
 
@@ -68745,26 +66975,26 @@ case OP_ReadCookie: {               /* out2-prerelease */
 ** A transaction must be started before executing this opcode.
 */
 case OP_SetCookie: {       /* in3 */
-#if 0  /* local variables moved into u.av */
+#if 0  /* local variables moved into u.aw */
   Db *pDb;
-#endif /* local variables moved into u.av */
+#endif /* local variables moved into u.aw */
   assert( pOp->p2<SQLITE_N_BTREE_META );
   assert( pOp->p1>=0 && pOp->p1<db->nDb );
   assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
-  u.av.pDb = &db->aDb[pOp->p1];
-  assert( u.av.pDb->pBt!=0 );
+  u.aw.pDb = &db->aDb[pOp->p1];
+  assert( u.aw.pDb->pBt!=0 );
   assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) );
   pIn3 = &aMem[pOp->p3];
   sqlite3VdbeMemIntegerify(pIn3);
   /* See note about index shifting on OP_ReadCookie */
-  rc = sqlite3BtreeUpdateMeta(u.av.pDb->pBt, pOp->p2, (int)pIn3->u.i);
+  rc = sqlite3BtreeUpdateMeta(u.aw.pDb->pBt, pOp->p2, (int)pIn3->u.i);
   if( pOp->p2==BTREE_SCHEMA_VERSION ){
     /* When the schema cookie changes, record the new cookie internally */
-    u.av.pDb->pSchema->schema_cookie = (int)pIn3->u.i;
+    u.aw.pDb->pSchema->schema_cookie = (int)pIn3->u.i;
     db->flags |= SQLITE_InternChanges;
   }else if( pOp->p2==BTREE_FILE_FORMAT ){
     /* Record changes in the file format */
-    u.av.pDb->pSchema->file_format = (u8)pIn3->u.i;
+    u.aw.pDb->pSchema->file_format = (u8)pIn3->u.i;
   }
   if( pOp->p1==1 ){
     /* Invalidate all prepared statements whenever the TEMP database
@@ -68794,23 +67024,23 @@ case OP_SetCookie: {       /* in3 */
 ** invoked.
 */
 case OP_VerifyCookie: {
-#if 0  /* local variables moved into u.aw */
+#if 0  /* local variables moved into u.ax */
   int iMeta;
   int iGen;
   Btree *pBt;
-#endif /* local variables moved into u.aw */
+#endif /* local variables moved into u.ax */
 
   assert( pOp->p1>=0 && pOp->p1<db->nDb );
   assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
   assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) );
-  u.aw.pBt = db->aDb[pOp->p1].pBt;
-  if( u.aw.pBt ){
-    sqlite3BtreeGetMeta(u.aw.pBt, BTREE_SCHEMA_VERSION, (u32 *)&u.aw.iMeta);
-    u.aw.iGen = db->aDb[pOp->p1].pSchema->iGeneration;
+  u.ax.pBt = db->aDb[pOp->p1].pBt;
+  if( u.ax.pBt ){
+    sqlite3BtreeGetMeta(u.ax.pBt, BTREE_SCHEMA_VERSION, (u32 *)&u.ax.iMeta);
+    u.ax.iGen = db->aDb[pOp->p1].pSchema->iGeneration;
   }else{
-    u.aw.iGen = u.aw.iMeta = 0;
+    u.ax.iGen = u.ax.iMeta = 0;
   }
-  if( u.aw.iMeta!=pOp->p2 || u.aw.iGen!=pOp->p3 ){
+  if( u.ax.iMeta!=pOp->p2 || u.ax.iGen!=pOp->p3 ){
     sqlite3DbFree(db, p->zErrMsg);
     p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed");
     /* If the schema-cookie from the database file matches the cookie
@@ -68826,7 +67056,7 @@ case OP_VerifyCookie: {
     ** to be invalidated whenever sqlite3_step() is called from within
     ** a v-table method.
     */
-    if( db->aDb[pOp->p1].pSchema->schema_cookie!=u.aw.iMeta ){
+    if( db->aDb[pOp->p1].pSchema->schema_cookie!=u.ax.iMeta ){
       sqlite3ResetOneSchema(db, pOp->p1);
     }
 
@@ -68887,7 +67117,7 @@ case OP_VerifyCookie: {
 */
 case OP_OpenRead:
 case OP_OpenWrite: {
-#if 0  /* local variables moved into u.ax */
+#if 0  /* local variables moved into u.ay */
   int nField;
   KeyInfo *pKeyInfo;
   int p2;
@@ -68896,62 +67126,67 @@ case OP_OpenWrite: {
   Btree *pX;
   VdbeCursor *pCur;
   Db *pDb;
-#endif /* local variables moved into u.ax */
+#endif /* local variables moved into u.ay */
+
+  assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 );
+  assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 );
 
   if( p->expired ){
     rc = SQLITE_ABORT;
     break;
   }
 
-  u.ax.nField = 0;
-  u.ax.pKeyInfo = 0;
-  u.ax.p2 = pOp->p2;
-  u.ax.iDb = pOp->p3;
-  assert( u.ax.iDb>=0 && u.ax.iDb<db->nDb );
-  assert( (p->btreeMask & (((yDbMask)1)<<u.ax.iDb))!=0 );
-  u.ax.pDb = &db->aDb[u.ax.iDb];
-  u.ax.pX = u.ax.pDb->pBt;
-  assert( u.ax.pX!=0 );
+  u.ay.nField = 0;
+  u.ay.pKeyInfo = 0;
+  u.ay.p2 = pOp->p2;
+  u.ay.iDb = pOp->p3;
+  assert( u.ay.iDb>=0 && u.ay.iDb<db->nDb );
+  assert( (p->btreeMask & (((yDbMask)1)<<u.ay.iDb))!=0 );
+  u.ay.pDb = &db->aDb[u.ay.iDb];
+  u.ay.pX = u.ay.pDb->pBt;
+  assert( u.ay.pX!=0 );
   if( pOp->opcode==OP_OpenWrite ){
-    u.ax.wrFlag = 1;
-    assert( sqlite3SchemaMutexHeld(db, u.ax.iDb, 0) );
-    if( u.ax.pDb->pSchema->file_format < p->minWriteFileFormat ){
-      p->minWriteFileFormat = u.ax.pDb->pSchema->file_format;
+    u.ay.wrFlag = 1;
+    assert( sqlite3SchemaMutexHeld(db, u.ay.iDb, 0) );
+    if( u.ay.pDb->pSchema->file_format < p->minWriteFileFormat ){
+      p->minWriteFileFormat = u.ay.pDb->pSchema->file_format;
     }
   }else{
-    u.ax.wrFlag = 0;
+    u.ay.wrFlag = 0;
   }
-  if( pOp->p5 ){
-    assert( u.ax.p2>0 );
-    assert( u.ax.p2<=p->nMem );
-    pIn2 = &aMem[u.ax.p2];
+  if( pOp->p5 & OPFLAG_P2ISREG ){
+    assert( u.ay.p2>0 );
+    assert( u.ay.p2<=p->nMem );
+    pIn2 = &aMem[u.ay.p2];
     assert( memIsValid(pIn2) );
     assert( (pIn2->flags & MEM_Int)!=0 );
     sqlite3VdbeMemIntegerify(pIn2);
-    u.ax.p2 = (int)pIn2->u.i;
-    /* The u.ax.p2 value always comes from a prior OP_CreateTable opcode and
-    ** that opcode will always set the u.ax.p2 value to 2 or more or else fail.
+    u.ay.p2 = (int)pIn2->u.i;
+    /* The u.ay.p2 value always comes from a prior OP_CreateTable opcode and
+    ** that opcode will always set the u.ay.p2 value to 2 or more or else fail.
     ** If there were a failure, the prepared statement would have halted
     ** before reaching this instruction. */
-    if( NEVER(u.ax.p2<2) ) {
+    if( NEVER(u.ay.p2<2) ) {
       rc = SQLITE_CORRUPT_BKPT;
       goto abort_due_to_error;
     }
   }
   if( pOp->p4type==P4_KEYINFO ){
-    u.ax.pKeyInfo = pOp->p4.pKeyInfo;
-    u.ax.pKeyInfo->enc = ENC(p->db);
-    u.ax.nField = u.ax.pKeyInfo->nField+1;
+    u.ay.pKeyInfo = pOp->p4.pKeyInfo;
+    u.ay.pKeyInfo->enc = ENC(p->db);
+    u.ay.nField = u.ay.pKeyInfo->nField+1;
   }else if( pOp->p4type==P4_INT32 ){
-    u.ax.nField = pOp->p4.i;
+    u.ay.nField = pOp->p4.i;
   }
   assert( pOp->p1>=0 );
-  u.ax.pCur = allocateCursor(p, pOp->p1, u.ax.nField, u.ax.iDb, 1);
-  if( u.ax.pCur==0 ) goto no_mem;
-  u.ax.pCur->nullRow = 1;
-  u.ax.pCur->isOrdered = 1;
-  rc = sqlite3BtreeCursor(u.ax.pX, u.ax.p2, u.ax.wrFlag, u.ax.pKeyInfo, u.ax.pCur->pCursor);
-  u.ax.pCur->pKeyInfo = u.ax.pKeyInfo;
+  u.ay.pCur = allocateCursor(p, pOp->p1, u.ay.nField, u.ay.iDb, 1);
+  if( u.ay.pCur==0 ) goto no_mem;
+  u.ay.pCur->nullRow = 1;
+  u.ay.pCur->isOrdered = 1;
+  rc = sqlite3BtreeCursor(u.ay.pX, u.ay.p2, u.ay.wrFlag, u.ay.pKeyInfo, u.ay.pCur->pCursor);
+  u.ay.pCur->pKeyInfo = u.ay.pKeyInfo;
+  assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
+  sqlite3BtreeCursorHints(u.ay.pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR));
 
   /* Since it performs no memory allocation or IO, the only value that
   ** sqlite3BtreeCursor() may return is SQLITE_OK. */
@@ -68961,8 +67196,8 @@ case OP_OpenWrite: {
   ** SQLite used to check if the root-page flags were sane at this point
   ** and report database corruption if they were not, but this check has
   ** since moved into the btree layer.  */
-  u.ax.pCur->isTable = pOp->p4type!=P4_KEYINFO;
-  u.ax.pCur->isIndex = !u.ax.pCur->isTable;
+  u.ay.pCur->isTable = pOp->p4type!=P4_KEYINFO;
+  u.ay.pCur->isIndex = !u.ay.pCur->isTable;
   break;
 }
 
@@ -68998,9 +67233,9 @@ case OP_OpenWrite: {
 */
 case OP_OpenAutoindex: 
 case OP_OpenEphemeral: {
-#if 0  /* local variables moved into u.ay */
+#if 0  /* local variables moved into u.az */
   VdbeCursor *pCx;
-#endif /* local variables moved into u.ay */
+#endif /* local variables moved into u.az */
   static const int vfsFlags =
       SQLITE_OPEN_READWRITE |
       SQLITE_OPEN_CREATE |
@@ -69009,13 +67244,13 @@ case OP_OpenEphemeral: {
       SQLITE_OPEN_TRANSIENT_DB;
 
   assert( pOp->p1>=0 );
-  u.ay.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
-  if( u.ay.pCx==0 ) goto no_mem;
-  u.ay.pCx->nullRow = 1;
-  rc = sqlite3BtreeOpen(db->pVfs, 0, db, &u.ay.pCx->pBt,
+  u.az.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
+  if( u.az.pCx==0 ) goto no_mem;
+  u.az.pCx->nullRow = 1;
+  rc = sqlite3BtreeOpen(db->pVfs, 0, db, &u.az.pCx->pBt,
                         BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags);
   if( rc==SQLITE_OK ){
-    rc = sqlite3BtreeBeginTrans(u.ay.pCx->pBt, 1);
+    rc = sqlite3BtreeBeginTrans(u.az.pCx->pBt, 1);
   }
   if( rc==SQLITE_OK ){
     /* If a transient index is required, create it by calling
@@ -69026,42 +67261,43 @@ case OP_OpenEphemeral: {
     if( pOp->p4.pKeyInfo ){
       int pgno;
       assert( pOp->p4type==P4_KEYINFO );
-      rc = sqlite3BtreeCreateTable(u.ay.pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5);
+      rc = sqlite3BtreeCreateTable(u.az.pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5);
       if( rc==SQLITE_OK ){
         assert( pgno==MASTER_ROOT+1 );
-        rc = sqlite3BtreeCursor(u.ay.pCx->pBt, pgno, 1,
-                                (KeyInfo*)pOp->p4.z, u.ay.pCx->pCursor);
-        u.ay.pCx->pKeyInfo = pOp->p4.pKeyInfo;
-        u.ay.pCx->pKeyInfo->enc = ENC(p->db);
+        rc = sqlite3BtreeCursor(u.az.pCx->pBt, pgno, 1,
+                                (KeyInfo*)pOp->p4.z, u.az.pCx->pCursor);
+        u.az.pCx->pKeyInfo = pOp->p4.pKeyInfo;
+        u.az.pCx->pKeyInfo->enc = ENC(p->db);
       }
-      u.ay.pCx->isTable = 0;
+      u.az.pCx->isTable = 0;
     }else{
-      rc = sqlite3BtreeCursor(u.ay.pCx->pBt, MASTER_ROOT, 1, 0, u.ay.pCx->pCursor);
-      u.ay.pCx->isTable = 1;
+      rc = sqlite3BtreeCursor(u.az.pCx->pBt, MASTER_ROOT, 1, 0, u.az.pCx->pCursor);
+      u.az.pCx->isTable = 1;
     }
   }
-  u.ay.pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
-  u.ay.pCx->isIndex = !u.ay.pCx->isTable;
+  u.az.pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
+  u.az.pCx->isIndex = !u.az.pCx->isTable;
   break;
 }
 
-/* Opcode: OpenSorter P1 P2 * P4 *
+/* Opcode: SorterOpen P1 P2 * P4 *
 **
 ** This opcode works like OP_OpenEphemeral except that it opens
 ** a transient index that is specifically designed to sort large
 ** tables using an external merge-sort algorithm.
 */
 case OP_SorterOpen: {
-#if 0  /* local variables moved into u.az */
+#if 0  /* local variables moved into u.ba */
   VdbeCursor *pCx;
-#endif /* local variables moved into u.az */
+#endif /* local variables moved into u.ba */
+
 #ifndef SQLITE_OMIT_MERGE_SORT
-  u.az.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
-  if( u.az.pCx==0 ) goto no_mem;
-  u.az.pCx->pKeyInfo = pOp->p4.pKeyInfo;
-  u.az.pCx->pKeyInfo->enc = ENC(p->db);
-  u.az.pCx->isSorter = 1;
-  rc = sqlite3VdbeSorterInit(db, u.az.pCx);
+  u.ba.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
+  if( u.ba.pCx==0 ) goto no_mem;
+  u.ba.pCx->pKeyInfo = pOp->p4.pKeyInfo;
+  u.ba.pCx->pKeyInfo->enc = ENC(p->db);
+  u.ba.pCx->isSorter = 1;
+  rc = sqlite3VdbeSorterInit(db, u.ba.pCx);
 #else
   pOp->opcode = OP_OpenEphemeral;
   pc--;
@@ -69069,12 +67305,13 @@ case OP_SorterOpen: {
   break;
 }
 
-/* Opcode: OpenPseudo P1 P2 P3 * *
+/* Opcode: OpenPseudo P1 P2 P3 * P5
 **
 ** Open a new cursor that points to a fake table that contains a single
 ** row of data.  The content of that one row in the content of memory
-** register P2.  In other words, cursor P1 becomes an alias for the 
-** MEM_Blob content contained in register P2.
+** register P2 when P5==0.  In other words, cursor P1 becomes an alias for the 
+** MEM_Blob content contained in register P2.  When P5==1, then the
+** row is represented by P3 consecutive registers beginning with P2.
 **
 ** A pseudo-table created by this opcode is used to hold a single
 ** row output from the sorter so that the row can be decomposed into
@@ -69085,17 +67322,18 @@ case OP_SorterOpen: {
 ** the pseudo-table.
 */
 case OP_OpenPseudo: {
-#if 0  /* local variables moved into u.ba */
+#if 0  /* local variables moved into u.bb */
   VdbeCursor *pCx;
-#endif /* local variables moved into u.ba */
+#endif /* local variables moved into u.bb */
 
   assert( pOp->p1>=0 );
-  u.ba.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0);
-  if( u.ba.pCx==0 ) goto no_mem;
-  u.ba.pCx->nullRow = 1;
-  u.ba.pCx->pseudoTableReg = pOp->p2;
-  u.ba.pCx->isTable = 1;
-  u.ba.pCx->isIndex = 0;
+  u.bb.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0);
+  if( u.bb.pCx==0 ) goto no_mem;
+  u.bb.pCx->nullRow = 1;
+  u.bb.pCx->pseudoTableReg = pOp->p2;
+  u.bb.pCx->isTable = 1;
+  u.bb.pCx->isIndex = 0;
+  u.bb.pCx->multiPseudo = pOp->p5;
   break;
 }
 
@@ -69167,35 +67405,35 @@ case OP_SeekLt:         /* jump, in3 */
 case OP_SeekLe:         /* jump, in3 */
 case OP_SeekGe:         /* jump, in3 */
 case OP_SeekGt: {       /* jump, in3 */
-#if 0  /* local variables moved into u.bb */
+#if 0  /* local variables moved into u.bc */
   int res;
   int oc;
   VdbeCursor *pC;
   UnpackedRecord r;
   int nField;
   i64 iKey;      /* The rowid we are to seek to */
-#endif /* local variables moved into u.bb */
+#endif /* local variables moved into u.bc */
 
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
   assert( pOp->p2!=0 );
-  u.bb.pC = p->apCsr[pOp->p1];
-  assert( u.bb.pC!=0 );
-  assert( u.bb.pC->pseudoTableReg==0 );
+  u.bc.pC = p->apCsr[pOp->p1];
+  assert( u.bc.pC!=0 );
+  assert( u.bc.pC->pseudoTableReg==0 );
   assert( OP_SeekLe == OP_SeekLt+1 );
   assert( OP_SeekGe == OP_SeekLt+2 );
   assert( OP_SeekGt == OP_SeekLt+3 );
-  assert( u.bb.pC->isOrdered );
-  if( ALWAYS(u.bb.pC->pCursor!=0) ){
-    u.bb.oc = pOp->opcode;
-    u.bb.pC->nullRow = 0;
-    if( u.bb.pC->isTable ){
+  assert( u.bc.pC->isOrdered );
+  if( ALWAYS(u.bc.pC->pCursor!=0) ){
+    u.bc.oc = pOp->opcode;
+    u.bc.pC->nullRow = 0;
+    if( u.bc.pC->isTable ){
       /* The input value in P3 might be of any type: integer, real, string,
       ** blob, or NULL.  But it needs to be an integer before we can do
       ** the seek, so covert it. */
       pIn3 = &aMem[pOp->p3];
       applyNumericAffinity(pIn3);
-      u.bb.iKey = sqlite3VdbeIntValue(pIn3);
-      u.bb.pC->rowidIsValid = 0;
+      u.bc.iKey = sqlite3VdbeIntValue(pIn3);
+      u.bc.pC->rowidIsValid = 0;
 
       /* If the P3 value could not be converted into an integer without
       ** loss of information, then special processing is required... */
@@ -69210,101 +67448,101 @@ case OP_SeekGt: {       /* jump, in3 */
         ** point number. */
         assert( (pIn3->flags & MEM_Real)!=0 );
 
-        if( u.bb.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.bb.iKey || pIn3->r>0) ){
+        if( u.bc.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.bc.iKey || pIn3->r>0) ){
           /* The P3 value is too large in magnitude to be expressed as an
           ** integer. */
-          u.bb.res = 1;
+          u.bc.res = 1;
           if( pIn3->r<0 ){
-            if( u.bb.oc>=OP_SeekGe ){  assert( u.bb.oc==OP_SeekGe || u.bb.oc==OP_SeekGt );
-              rc = sqlite3BtreeFirst(u.bb.pC->pCursor, &u.bb.res);
+            if( u.bc.oc>=OP_SeekGe ){  assert( u.bc.oc==OP_SeekGe || u.bc.oc==OP_SeekGt );
+              rc = sqlite3BtreeFirst(u.bc.pC->pCursor, &u.bc.res);
               if( rc!=SQLITE_OK ) goto abort_due_to_error;
             }
           }else{
-            if( u.bb.oc<=OP_SeekLe ){  assert( u.bb.oc==OP_SeekLt || u.bb.oc==OP_SeekLe );
-              rc = sqlite3BtreeLast(u.bb.pC->pCursor, &u.bb.res);
+            if( u.bc.oc<=OP_SeekLe ){  assert( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekLe );
+              rc = sqlite3BtreeLast(u.bc.pC->pCursor, &u.bc.res);
               if( rc!=SQLITE_OK ) goto abort_due_to_error;
             }
           }
-          if( u.bb.res ){
+          if( u.bc.res ){
             pc = pOp->p2 - 1;
           }
           break;
-        }else if( u.bb.oc==OP_SeekLt || u.bb.oc==OP_SeekGe ){
+        }else if( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekGe ){
           /* Use the ceiling() function to convert real->int */
-          if( pIn3->r > (double)u.bb.iKey ) u.bb.iKey++;
+          if( pIn3->r > (double)u.bc.iKey ) u.bc.iKey++;
         }else{
           /* Use the floor() function to convert real->int */
-          assert( u.bb.oc==OP_SeekLe || u.bb.oc==OP_SeekGt );
-          if( pIn3->r < (double)u.bb.iKey ) u.bb.iKey--;
+          assert( u.bc.oc==OP_SeekLe || u.bc.oc==OP_SeekGt );
+          if( pIn3->r < (double)u.bc.iKey ) u.bc.iKey--;
         }
       }
-      rc = sqlite3BtreeMovetoUnpacked(u.bb.pC->pCursor, 0, (u64)u.bb.iKey, 0, &u.bb.res);
+      rc = sqlite3BtreeMovetoUnpacked(u.bc.pC->pCursor, 0, (u64)u.bc.iKey, 0, &u.bc.res);
       if( rc!=SQLITE_OK ){
         goto abort_due_to_error;
       }
-      if( u.bb.res==0 ){
-        u.bb.pC->rowidIsValid = 1;
-        u.bb.pC->lastRowid = u.bb.iKey;
+      if( u.bc.res==0 ){
+        u.bc.pC->rowidIsValid = 1;
+        u.bc.pC->lastRowid = u.bc.iKey;
       }
     }else{
-      u.bb.nField = pOp->p4.i;
+      u.bc.nField = pOp->p4.i;
       assert( pOp->p4type==P4_INT32 );
-      assert( u.bb.nField>0 );
-      u.bb.r.pKeyInfo = u.bb.pC->pKeyInfo;
-      u.bb.r.nField = (u16)u.bb.nField;
+      assert( u.bc.nField>0 );
+      u.bc.r.pKeyInfo = u.bc.pC->pKeyInfo;
+      u.bc.r.nField = (u16)u.bc.nField;
 
       /* The next line of code computes as follows, only faster:
-      **   if( u.bb.oc==OP_SeekGt || u.bb.oc==OP_SeekLe ){
-      **     u.bb.r.flags = UNPACKED_INCRKEY;
+      **   if( u.bc.oc==OP_SeekGt || u.bc.oc==OP_SeekLe ){
+      **     u.bc.r.flags = UNPACKED_INCRKEY;
       **   }else{
-      **     u.bb.r.flags = 0;
+      **     u.bc.r.flags = 0;
       **   }
       */
-      u.bb.r.flags = (u16)(UNPACKED_INCRKEY * (1 & (u.bb.oc - OP_SeekLt)));
-      assert( u.bb.oc!=OP_SeekGt || u.bb.r.flags==UNPACKED_INCRKEY );
-      assert( u.bb.oc!=OP_SeekLe || u.bb.r.flags==UNPACKED_INCRKEY );
-      assert( u.bb.oc!=OP_SeekGe || u.bb.r.flags==0 );
-      assert( u.bb.oc!=OP_SeekLt || u.bb.r.flags==0 );
+      u.bc.r.flags = (u16)(UNPACKED_INCRKEY * (1 & (u.bc.oc - OP_SeekLt)));
+      assert( u.bc.oc!=OP_SeekGt || u.bc.r.flags==UNPACKED_INCRKEY );
+      assert( u.bc.oc!=OP_SeekLe || u.bc.r.flags==UNPACKED_INCRKEY );
+      assert( u.bc.oc!=OP_SeekGe || u.bc.r.flags==0 );
+      assert( u.bc.oc!=OP_SeekLt || u.bc.r.flags==0 );
 
-      u.bb.r.aMem = &aMem[pOp->p3];
+      u.bc.r.aMem = &aMem[pOp->p3];
 #ifdef SQLITE_DEBUG
-      { int i; for(i=0; i<u.bb.r.nField; i++) assert( memIsValid(&u.bb.r.aMem[i]) ); }
+      { int i; for(i=0; i<u.bc.r.nField; i++) assert( memIsValid(&u.bc.r.aMem[i]) ); }
 #endif
-      ExpandBlob(u.bb.r.aMem);
-      rc = sqlite3BtreeMovetoUnpacked(u.bb.pC->pCursor, &u.bb.r, 0, 0, &u.bb.res);
+      ExpandBlob(u.bc.r.aMem);
+      rc = sqlite3BtreeMovetoUnpacked(u.bc.pC->pCursor, &u.bc.r, 0, 0, &u.bc.res);
       if( rc!=SQLITE_OK ){
         goto abort_due_to_error;
       }
-      u.bb.pC->rowidIsValid = 0;
+      u.bc.pC->rowidIsValid = 0;
     }
-    u.bb.pC->deferredMoveto = 0;
-    u.bb.pC->cacheStatus = CACHE_STALE;
+    u.bc.pC->deferredMoveto = 0;
+    u.bc.pC->cacheStatus = CACHE_STALE;
 #ifdef SQLITE_TEST
     sqlite3_search_count++;
 #endif
-    if( u.bb.oc>=OP_SeekGe ){  assert( u.bb.oc==OP_SeekGe || u.bb.oc==OP_SeekGt );
-      if( u.bb.res<0 || (u.bb.res==0 && u.bb.oc==OP_SeekGt) ){
-        rc = sqlite3BtreeNext(u.bb.pC->pCursor, &u.bb.res);
+    if( u.bc.oc>=OP_SeekGe ){  assert( u.bc.oc==OP_SeekGe || u.bc.oc==OP_SeekGt );
+      if( u.bc.res<0 || (u.bc.res==0 && u.bc.oc==OP_SeekGt) ){
+        rc = sqlite3BtreeNext(u.bc.pC->pCursor, &u.bc.res);
         if( rc!=SQLITE_OK ) goto abort_due_to_error;
-        u.bb.pC->rowidIsValid = 0;
+        u.bc.pC->rowidIsValid = 0;
       }else{
-        u.bb.res = 0;
+        u.bc.res = 0;
       }
     }else{
-      assert( u.bb.oc==OP_SeekLt || u.bb.oc==OP_SeekLe );
-      if( u.bb.res>0 || (u.bb.res==0 && u.bb.oc==OP_SeekLt) ){
-        rc = sqlite3BtreePrevious(u.bb.pC->pCursor, &u.bb.res);
+      assert( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekLe );
+      if( u.bc.res>0 || (u.bc.res==0 && u.bc.oc==OP_SeekLt) ){
+        rc = sqlite3BtreePrevious(u.bc.pC->pCursor, &u.bc.res);
         if( rc!=SQLITE_OK ) goto abort_due_to_error;
-        u.bb.pC->rowidIsValid = 0;
+        u.bc.pC->rowidIsValid = 0;
       }else{
-        /* u.bb.res might be negative because the table is empty.  Check to
+        /* u.bc.res might be negative because the table is empty.  Check to
         ** see if this is the case.
         */
-        u.bb.res = sqlite3BtreeEof(u.bb.pC->pCursor);
+        u.bc.res = sqlite3BtreeEof(u.bc.pC->pCursor);
       }
     }
     assert( pOp->p2>0 );
-    if( u.bb.res ){
+    if( u.bc.res ){
       pc = pOp->p2 - 1;
     }
   }else{
@@ -69327,20 +67565,20 @@ case OP_SeekGt: {       /* jump, in3 */
 ** occur, no unnecessary I/O happens.
 */
 case OP_Seek: {    /* in2 */
-#if 0  /* local variables moved into u.bc */
+#if 0  /* local variables moved into u.bd */
   VdbeCursor *pC;
-#endif /* local variables moved into u.bc */
+#endif /* local variables moved into u.bd */
 
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
-  u.bc.pC = p->apCsr[pOp->p1];
-  assert( u.bc.pC!=0 );
-  if( ALWAYS(u.bc.pC->pCursor!=0) ){
-    assert( u.bc.pC->isTable );
-    u.bc.pC->nullRow = 0;
+  u.bd.pC = p->apCsr[pOp->p1];
+  assert( u.bd.pC!=0 );
+  if( ALWAYS(u.bd.pC->pCursor!=0) ){
+    assert( u.bd.pC->isTable );
+    u.bd.pC->nullRow = 0;
     pIn2 = &aMem[pOp->p2];
-    u.bc.pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
-    u.bc.pC->rowidIsValid = 0;
-    u.bc.pC->deferredMoveto = 1;
+    u.bd.pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
+    u.bd.pC->rowidIsValid = 0;
+    u.bd.pC->deferredMoveto = 1;
   }
   break;
 }
@@ -69372,7 +67610,7 @@ case OP_Seek: {    /* in2 */
 */
 case OP_NotFound:       /* jump, in3 */
 case OP_Found: {        /* jump, in3 */
-#if 0  /* local variables moved into u.bd */
+#if 0  /* local variables moved into u.be */
   int alreadyExists;
   VdbeCursor *pC;
   int res;
@@ -69380,55 +67618,55 @@ case OP_Found: {        /* jump, in3 */
   UnpackedRecord *pIdxKey;
   UnpackedRecord r;
   char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7];
-#endif /* local variables moved into u.bd */
+#endif /* local variables moved into u.be */
 
 #ifdef SQLITE_TEST
   sqlite3_found_count++;
 #endif
 
-  u.bd.alreadyExists = 0;
+  u.be.alreadyExists = 0;
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
   assert( pOp->p4type==P4_INT32 );
-  u.bd.pC = p->apCsr[pOp->p1];
-  assert( u.bd.pC!=0 );
+  u.be.pC = p->apCsr[pOp->p1];
+  assert( u.be.pC!=0 );
   pIn3 = &aMem[pOp->p3];
-  if( ALWAYS(u.bd.pC->pCursor!=0) ){
+  if( ALWAYS(u.be.pC->pCursor!=0) ){
 
-    assert( u.bd.pC->isTable==0 );
+    assert( u.be.pC->isTable==0 );
     if( pOp->p4.i>0 ){
-      u.bd.r.pKeyInfo = u.bd.pC->pKeyInfo;
-      u.bd.r.nField = (u16)pOp->p4.i;
-      u.bd.r.aMem = pIn3;
+      u.be.r.pKeyInfo = u.be.pC->pKeyInfo;
+      u.be.r.nField = (u16)pOp->p4.i;
+      u.be.r.aMem = pIn3;
 #ifdef SQLITE_DEBUG
-      { int i; for(i=0; i<u.bd.r.nField; i++) assert( memIsValid(&u.bd.r.aMem[i]) ); }
+      { int i; for(i=0; i<u.be.r.nField; i++) assert( memIsValid(&u.be.r.aMem[i]) ); }
 #endif
-      u.bd.r.flags = UNPACKED_PREFIX_MATCH;
-      u.bd.pIdxKey = &u.bd.r;
+      u.be.r.flags = UNPACKED_PREFIX_MATCH;
+      u.be.pIdxKey = &u.be.r;
     }else{
-      u.bd.pIdxKey = sqlite3VdbeAllocUnpackedRecord(
-          u.bd.pC->pKeyInfo, u.bd.aTempRec, sizeof(u.bd.aTempRec), &u.bd.pFree
+      u.be.pIdxKey = sqlite3VdbeAllocUnpackedRecord(
+          u.be.pC->pKeyInfo, u.be.aTempRec, sizeof(u.be.aTempRec), &u.be.pFree
       );
-      if( u.bd.pIdxKey==0 ) goto no_mem;
+      if( u.be.pIdxKey==0 ) goto no_mem;
       assert( pIn3->flags & MEM_Blob );
       assert( (pIn3->flags & MEM_Zero)==0 );  /* zeroblobs already expanded */
-      sqlite3VdbeRecordUnpack(u.bd.pC->pKeyInfo, pIn3->n, pIn3->z, u.bd.pIdxKey);
-      u.bd.pIdxKey->flags |= UNPACKED_PREFIX_MATCH;
+      sqlite3VdbeRecordUnpack(u.be.pC->pKeyInfo, pIn3->n, pIn3->z, u.be.pIdxKey);
+      u.be.pIdxKey->flags |= UNPACKED_PREFIX_MATCH;
     }
-    rc = sqlite3BtreeMovetoUnpacked(u.bd.pC->pCursor, u.bd.pIdxKey, 0, 0, &u.bd.res);
+    rc = sqlite3BtreeMovetoUnpacked(u.be.pC->pCursor, u.be.pIdxKey, 0, 0, &u.be.res);
     if( pOp->p4.i==0 ){
-      sqlite3DbFree(db, u.bd.pFree);
+      sqlite3DbFree(db, u.be.pFree);
     }
     if( rc!=SQLITE_OK ){
       break;
     }
-    u.bd.alreadyExists = (u.bd.res==0);
-    u.bd.pC->deferredMoveto = 0;
-    u.bd.pC->cacheStatus = CACHE_STALE;
+    u.be.alreadyExists = (u.be.res==0);
+    u.be.pC->deferredMoveto = 0;
+    u.be.pC->cacheStatus = CACHE_STALE;
   }
   if( pOp->opcode==OP_Found ){
-    if( u.bd.alreadyExists ) pc = pOp->p2 - 1;
+    if( u.be.alreadyExists ) pc = pOp->p2 - 1;
   }else{
-    if( !u.bd.alreadyExists ) pc = pOp->p2 - 1;
+    if( !u.be.alreadyExists ) pc = pOp->p2 - 1;
   }
   break;
 }
@@ -69460,7 +67698,7 @@ case OP_Found: {        /* jump, in3 */
 ** See also: NotFound, NotExists, Found
 */
 case OP_IsUnique: {        /* jump, in3 */
-#if 0  /* local variables moved into u.be */
+#if 0  /* local variables moved into u.bf */
   u16 ii;
   VdbeCursor *pCx;
   BtCursor *pCrsr;
@@ -69468,55 +67706,55 @@ case OP_IsUnique: {        /* jump, in3 */
   Mem *aMx;
   UnpackedRecord r;                  /* B-Tree index search key */
   i64 R;                             /* Rowid stored in register P3 */
-#endif /* local variables moved into u.be */
+#endif /* local variables moved into u.bf */
 
   pIn3 = &aMem[pOp->p3];
-  u.be.aMx = &aMem[pOp->p4.i];
+  u.bf.aMx = &aMem[pOp->p4.i];
   /* Assert that the values of parameters P1 and P4 are in range. */
   assert( pOp->p4type==P4_INT32 );
   assert( pOp->p4.i>0 && pOp->p4.i<=p->nMem );
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
 
   /* Find the index cursor. */
-  u.be.pCx = p->apCsr[pOp->p1];
-  assert( u.be.pCx->deferredMoveto==0 );
-  u.be.pCx->seekResult = 0;
-  u.be.pCx->cacheStatus = CACHE_STALE;
-  u.be.pCrsr = u.be.pCx->pCursor;
+  u.bf.pCx = p->apCsr[pOp->p1];
+  assert( u.bf.pCx->deferredMoveto==0 );
+  u.bf.pCx->seekResult = 0;
+  u.bf.pCx->cacheStatus = CACHE_STALE;
+  u.bf.pCrsr = u.bf.pCx->pCursor;
 
   /* If any of the values are NULL, take the jump. */
-  u.be.nField = u.be.pCx->pKeyInfo->nField;
-  for(u.be.ii=0; u.be.ii<u.be.nField; u.be.ii++){
-    if( u.be.aMx[u.be.ii].flags & MEM_Null ){
+  u.bf.nField = u.bf.pCx->pKeyInfo->nField;
+  for(u.bf.ii=0; u.bf.ii<u.bf.nField; u.bf.ii++){
+    if( u.bf.aMx[u.bf.ii].flags & MEM_Null ){
       pc = pOp->p2 - 1;
-      u.be.pCrsr = 0;
+      u.bf.pCrsr = 0;
       break;
     }
   }
-  assert( (u.be.aMx[u.be.nField].flags & MEM_Null)==0 );
+  assert( (u.bf.aMx[u.bf.nField].flags & MEM_Null)==0 );
 
-  if( u.be.pCrsr!=0 ){
+  if( u.bf.pCrsr!=0 ){
     /* Populate the index search key. */
-    u.be.r.pKeyInfo = u.be.pCx->pKeyInfo;
-    u.be.r.nField = u.be.nField + 1;
-    u.be.r.flags = UNPACKED_PREFIX_SEARCH;
-    u.be.r.aMem = u.be.aMx;
+    u.bf.r.pKeyInfo = u.bf.pCx->pKeyInfo;
+    u.bf.r.nField = u.bf.nField + 1;
+    u.bf.r.flags = UNPACKED_PREFIX_SEARCH;
+    u.bf.r.aMem = u.bf.aMx;
 #ifdef SQLITE_DEBUG
-    { int i; for(i=0; i<u.be.r.nField; i++) assert( memIsValid(&u.be.r.aMem[i]) ); }
+    { int i; for(i=0; i<u.bf.r.nField; i++) assert( memIsValid(&u.bf.r.aMem[i]) ); }
 #endif
 
-    /* Extract the value of u.be.R from register P3. */
+    /* Extract the value of u.bf.R from register P3. */
     sqlite3VdbeMemIntegerify(pIn3);
-    u.be.R = pIn3->u.i;
+    u.bf.R = pIn3->u.i;
 
     /* Search the B-Tree index. If no conflicting record is found, jump
     ** to P2. Otherwise, copy the rowid of the conflicting record to
     ** register P3 and fall through to the next instruction.  */
-    rc = sqlite3BtreeMovetoUnpacked(u.be.pCrsr, &u.be.r, 0, 0, &u.be.pCx->seekResult);
-    if( (u.be.r.flags & UNPACKED_PREFIX_SEARCH) || u.be.r.rowid==u.be.R ){
+    rc = sqlite3BtreeMovetoUnpacked(u.bf.pCrsr, &u.bf.r, 0, 0, &u.bf.pCx->seekResult);
+    if( (u.bf.r.flags & UNPACKED_PREFIX_SEARCH) || u.bf.r.rowid==u.bf.R ){
       pc = pOp->p2 - 1;
     }else{
-      pIn3->u.i = u.be.r.rowid;
+      pIn3->u.i = u.bf.r.rowid;
     }
   }
   break;
@@ -69537,42 +67775,42 @@ case OP_IsUnique: {        /* jump, in3 */
 ** See also: Found, NotFound, IsUnique
 */
 case OP_NotExists: {        /* jump, in3 */
-#if 0  /* local variables moved into u.bf */
+#if 0  /* local variables moved into u.bg */
   VdbeCursor *pC;
   BtCursor *pCrsr;
   int res;
   u64 iKey;
-#endif /* local variables moved into u.bf */
+#endif /* local variables moved into u.bg */
 
   pIn3 = &aMem[pOp->p3];
   assert( pIn3->flags & MEM_Int );
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
-  u.bf.pC = p->apCsr[pOp->p1];
-  assert( u.bf.pC!=0 );
-  assert( u.bf.pC->isTable );
-  assert( u.bf.pC->pseudoTableReg==0 );
-  u.bf.pCrsr = u.bf.pC->pCursor;
-  if( ALWAYS(u.bf.pCrsr!=0) ){
-    u.bf.res = 0;
-    u.bf.iKey = pIn3->u.i;
-    rc = sqlite3BtreeMovetoUnpacked(u.bf.pCrsr, 0, u.bf.iKey, 0, &u.bf.res);
-    u.bf.pC->lastRowid = pIn3->u.i;
-    u.bf.pC->rowidIsValid = u.bf.res==0 ?1:0;
-    u.bf.pC->nullRow = 0;
-    u.bf.pC->cacheStatus = CACHE_STALE;
-    u.bf.pC->deferredMoveto = 0;
-    if( u.bf.res!=0 ){
+  u.bg.pC = p->apCsr[pOp->p1];
+  assert( u.bg.pC!=0 );
+  assert( u.bg.pC->isTable );
+  assert( u.bg.pC->pseudoTableReg==0 );
+  u.bg.pCrsr = u.bg.pC->pCursor;
+  if( ALWAYS(u.bg.pCrsr!=0) ){
+    u.bg.res = 0;
+    u.bg.iKey = pIn3->u.i;
+    rc = sqlite3BtreeMovetoUnpacked(u.bg.pCrsr, 0, u.bg.iKey, 0, &u.bg.res);
+    u.bg.pC->lastRowid = pIn3->u.i;
+    u.bg.pC->rowidIsValid = u.bg.res==0 ?1:0;
+    u.bg.pC->nullRow = 0;
+    u.bg.pC->cacheStatus = CACHE_STALE;
+    u.bg.pC->deferredMoveto = 0;
+    if( u.bg.res!=0 ){
       pc = pOp->p2 - 1;
-      assert( u.bf.pC->rowidIsValid==0 );
+      assert( u.bg.pC->rowidIsValid==0 );
     }
-    u.bf.pC->seekResult = u.bf.res;
+    u.bg.pC->seekResult = u.bg.res;
   }else{
     /* This happens when an attempt to open a read cursor on the
     ** sqlite_master table returns SQLITE_EMPTY.
     */
     pc = pOp->p2 - 1;
-    assert( u.bf.pC->rowidIsValid==0 );
-    u.bf.pC->seekResult = 0;
+    assert( u.bg.pC->rowidIsValid==0 );
+    u.bg.pC->seekResult = 0;
   }
   break;
 }
@@ -69607,21 +67845,21 @@ case OP_Sequence: {           /* out2-prerelease */
 ** AUTOINCREMENT feature.
 */
 case OP_NewRowid: {           /* out2-prerelease */
-#if 0  /* local variables moved into u.bg */
+#if 0  /* local variables moved into u.bh */
   i64 v;                 /* The new rowid */
   VdbeCursor *pC;        /* Cursor of table to get the new rowid */
   int res;               /* Result of an sqlite3BtreeLast() */
   int cnt;               /* Counter to limit the number of searches */
   Mem *pMem;             /* Register holding largest rowid for AUTOINCREMENT */
   VdbeFrame *pFrame;     /* Root frame of VDBE */
-#endif /* local variables moved into u.bg */
+#endif /* local variables moved into u.bh */
 
-  u.bg.v = 0;
-  u.bg.res = 0;
+  u.bh.v = 0;
+  u.bh.res = 0;
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
-  u.bg.pC = p->apCsr[pOp->p1];
-  assert( u.bg.pC!=0 );
-  if( NEVER(u.bg.pC->pCursor==0) ){
+  u.bh.pC = p->apCsr[pOp->p1];
+  assert( u.bh.pC!=0 );
+  if( NEVER(u.bh.pC->pCursor==0) ){
     /* The zero initialization above is all that is needed */
   }else{
     /* The next rowid or record number (different terms for the same
@@ -69637,7 +67875,7 @@ case OP_NewRowid: {           /* out2-prerelease */
     ** succeeded.  If the random rowid does exist, we select a new one
     ** and try again, up to 100 times.
     */
-    assert( u.bg.pC->isTable );
+    assert( u.bh.pC->isTable );
 
 #ifdef SQLITE_32BIT_ROWID
 #   define MAX_ROWID 0x7fffffff
@@ -69649,23 +67887,23 @@ case OP_NewRowid: {           /* out2-prerelease */
 #   define MAX_ROWID  (i64)( (((u64)0x7fffffff)<<32) | (u64)0xffffffff )
 #endif
 
-    if( !u.bg.pC->useRandomRowid ){
-      u.bg.v = sqlite3BtreeGetCachedRowid(u.bg.pC->pCursor);
-      if( u.bg.v==0 ){
-        rc = sqlite3BtreeLast(u.bg.pC->pCursor, &u.bg.res);
+    if( !u.bh.pC->useRandomRowid ){
+      u.bh.v = sqlite3BtreeGetCachedRowid(u.bh.pC->pCursor);
+      if( u.bh.v==0 ){
+        rc = sqlite3BtreeLast(u.bh.pC->pCursor, &u.bh.res);
         if( rc!=SQLITE_OK ){
           goto abort_due_to_error;
         }
-        if( u.bg.res ){
-          u.bg.v = 1;   /* IMP: R-61914-48074 */
+        if( u.bh.res ){
+          u.bh.v = 1;   /* IMP: R-61914-48074 */
         }else{
-          assert( sqlite3BtreeCursorIsValid(u.bg.pC->pCursor) );
-          rc = sqlite3BtreeKeySize(u.bg.pC->pCursor, &u.bg.v);
+          assert( sqlite3BtreeCursorIsValid(u.bh.pC->pCursor) );
+          rc = sqlite3BtreeKeySize(u.bh.pC->pCursor, &u.bh.v);
           assert( rc==SQLITE_OK );   /* Cannot fail following BtreeLast() */
-          if( u.bg.v>=MAX_ROWID ){
-            u.bg.pC->useRandomRowid = 1;
+          if( u.bh.v>=MAX_ROWID ){
+            u.bh.pC->useRandomRowid = 1;
           }else{
-            u.bg.v++;   /* IMP: R-29538-34987 */
+            u.bh.v++;   /* IMP: R-29538-34987 */
           }
         }
       }
@@ -69675,35 +67913,35 @@ case OP_NewRowid: {           /* out2-prerelease */
         /* Assert that P3 is a valid memory cell. */
         assert( pOp->p3>0 );
         if( p->pFrame ){
-          for(u.bg.pFrame=p->pFrame; u.bg.pFrame->pParent; u.bg.pFrame=u.bg.pFrame->pParent);
+          for(u.bh.pFrame=p->pFrame; u.bh.pFrame->pParent; u.bh.pFrame=u.bh.pFrame->pParent);
           /* Assert that P3 is a valid memory cell. */
-          assert( pOp->p3<=u.bg.pFrame->nMem );
-          u.bg.pMem = &u.bg.pFrame->aMem[pOp->p3];
+          assert( pOp->p3<=u.bh.pFrame->nMem );
+          u.bh.pMem = &u.bh.pFrame->aMem[pOp->p3];
         }else{
           /* Assert that P3 is a valid memory cell. */
           assert( pOp->p3<=p->nMem );
-          u.bg.pMem = &aMem[pOp->p3];
-          memAboutToChange(p, u.bg.pMem);
+          u.bh.pMem = &aMem[pOp->p3];
+          memAboutToChange(p, u.bh.pMem);
         }
-        assert( memIsValid(u.bg.pMem) );
+        assert( memIsValid(u.bh.pMem) );
 
-        REGISTER_TRACE(pOp->p3, u.bg.pMem);
-        sqlite3VdbeMemIntegerify(u.bg.pMem);
-        assert( (u.bg.pMem->flags & MEM_Int)!=0 );  /* mem(P3) holds an integer */
-        if( u.bg.pMem->u.i==MAX_ROWID || u.bg.pC->useRandomRowid ){
+        REGISTER_TRACE(pOp->p3, u.bh.pMem);
+        sqlite3VdbeMemIntegerify(u.bh.pMem);
+        assert( (u.bh.pMem->flags & MEM_Int)!=0 );  /* mem(P3) holds an integer */
+        if( u.bh.pMem->u.i==MAX_ROWID || u.bh.pC->useRandomRowid ){
           rc = SQLITE_FULL;   /* IMP: R-12275-61338 */
           goto abort_due_to_error;
         }
-        if( u.bg.v<u.bg.pMem->u.i+1 ){
-          u.bg.v = u.bg.pMem->u.i + 1;
+        if( u.bh.v<u.bh.pMem->u.i+1 ){
+          u.bh.v = u.bh.pMem->u.i + 1;
         }
-        u.bg.pMem->u.i = u.bg.v;
+        u.bh.pMem->u.i = u.bh.v;
       }
 #endif
 
-      sqlite3BtreeSetCachedRowid(u.bg.pC->pCursor, u.bg.v<MAX_ROWID ? u.bg.v+1 : 0);
+      sqlite3BtreeSetCachedRowid(u.bh.pC->pCursor, u.bh.v<MAX_ROWID ? u.bh.v+1 : 0);
     }
-    if( u.bg.pC->useRandomRowid ){
+    if( u.bh.pC->useRandomRowid ){
       /* IMPLEMENTATION-OF: R-07677-41881 If the largest ROWID is equal to the
       ** largest possible integer (9223372036854775807) then the database
       ** engine starts picking positive candidate ROWIDs at random until
@@ -69711,35 +67949,35 @@ case OP_NewRowid: {           /* out2-prerelease */
       assert( pOp->p3==0 );  /* We cannot be in random rowid mode if this is
                              ** an AUTOINCREMENT table. */
       /* on the first attempt, simply do one more than previous */
-      u.bg.v = lastRowid;
-      u.bg.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */
-      u.bg.v++; /* ensure non-zero */
-      u.bg.cnt = 0;
-      while(   ((rc = sqlite3BtreeMovetoUnpacked(u.bg.pC->pCursor, 0, (u64)u.bg.v,
-                                                 0, &u.bg.res))==SQLITE_OK)
-            && (u.bg.res==0)
-            && (++u.bg.cnt<100)){
+      u.bh.v = lastRowid;
+      u.bh.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */
+      u.bh.v++; /* ensure non-zero */
+      u.bh.cnt = 0;
+      while(   ((rc = sqlite3BtreeMovetoUnpacked(u.bh.pC->pCursor, 0, (u64)u.bh.v,
+                                                 0, &u.bh.res))==SQLITE_OK)
+            && (u.bh.res==0)
+            && (++u.bh.cnt<100)){
         /* collision - try another random rowid */
-        sqlite3_randomness(sizeof(u.bg.v), &u.bg.v);
-        if( u.bg.cnt<5 ){
+        sqlite3_randomness(sizeof(u.bh.v), &u.bh.v);
+        if( u.bh.cnt<5 ){
           /* try "small" random rowids for the initial attempts */
-          u.bg.v &= 0xffffff;
+          u.bh.v &= 0xffffff;
         }else{
-          u.bg.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */
+          u.bh.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */
         }
-        u.bg.v++; /* ensure non-zero */
+        u.bh.v++; /* ensure non-zero */
       }
-      if( rc==SQLITE_OK && u.bg.res==0 ){
+      if( rc==SQLITE_OK && u.bh.res==0 ){
         rc = SQLITE_FULL;   /* IMP: R-38219-53002 */
         goto abort_due_to_error;
       }
-      assert( u.bg.v>0 );  /* EV: R-40812-03570 */
+      assert( u.bh.v>0 );  /* EV: R-40812-03570 */
     }
-    u.bg.pC->rowidIsValid = 0;
-    u.bg.pC->deferredMoveto = 0;
-    u.bg.pC->cacheStatus = CACHE_STALE;
+    u.bh.pC->rowidIsValid = 0;
+    u.bh.pC->deferredMoveto = 0;
+    u.bh.pC->cacheStatus = CACHE_STALE;
   }
-  pOut->u.i = u.bg.v;
+  pOut->u.i = u.bh.v;
   break;
 }
 
@@ -69789,7 +68027,7 @@ case OP_NewRowid: {           /* out2-prerelease */
 */
 case OP_Insert: 
 case OP_InsertInt: {
-#if 0  /* local variables moved into u.bh */
+#if 0  /* local variables moved into u.bi */
   Mem *pData;       /* MEM cell holding data for the record to be inserted */
   Mem *pKey;        /* MEM cell holding key  for the record */
   i64 iKey;         /* The integer ROWID or key for the record to be inserted */
@@ -69799,60 +68037,60 @@ case OP_InsertInt: {
   const char *zDb;  /* database name - used by the update hook */
   const char *zTbl; /* Table name - used by the opdate hook */
   int op;           /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */
-#endif /* local variables moved into u.bh */
+#endif /* local variables moved into u.bi */
 
-  u.bh.pData = &aMem[pOp->p2];
+  u.bi.pData = &aMem[pOp->p2];
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
-  assert( memIsValid(u.bh.pData) );
-  u.bh.pC = p->apCsr[pOp->p1];
-  assert( u.bh.pC!=0 );
-  assert( u.bh.pC->pCursor!=0 );
-  assert( u.bh.pC->pseudoTableReg==0 );
-  assert( u.bh.pC->isTable );
-  REGISTER_TRACE(pOp->p2, u.bh.pData);
+  assert( memIsValid(u.bi.pData) );
+  u.bi.pC = p->apCsr[pOp->p1];
+  assert( u.bi.pC!=0 );
+  assert( u.bi.pC->pCursor!=0 );
+  assert( u.bi.pC->pseudoTableReg==0 );
+  assert( u.bi.pC->isTable );
+  REGISTER_TRACE(pOp->p2, u.bi.pData);
 
   if( pOp->opcode==OP_Insert ){
-    u.bh.pKey = &aMem[pOp->p3];
-    assert( u.bh.pKey->flags & MEM_Int );
-    assert( memIsValid(u.bh.pKey) );
-    REGISTER_TRACE(pOp->p3, u.bh.pKey);
-    u.bh.iKey = u.bh.pKey->u.i;
+    u.bi.pKey = &aMem[pOp->p3];
+    assert( u.bi.pKey->flags & MEM_Int );
+    assert( memIsValid(u.bi.pKey) );
+    REGISTER_TRACE(pOp->p3, u.bi.pKey);
+    u.bi.iKey = u.bi.pKey->u.i;
   }else{
     assert( pOp->opcode==OP_InsertInt );
-    u.bh.iKey = pOp->p3;
+    u.bi.iKey = pOp->p3;
   }
 
   if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
-  if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = u.bh.iKey;
-  if( u.bh.pData->flags & MEM_Null ){
-    u.bh.pData->z = 0;
-    u.bh.pData->n = 0;
+  if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = u.bi.iKey;
+  if( u.bi.pData->flags & MEM_Null ){
+    u.bi.pData->z = 0;
+    u.bi.pData->n = 0;
   }else{
-    assert( u.bh.pData->flags & (MEM_Blob|MEM_Str) );
+    assert( u.bi.pData->flags & (MEM_Blob|MEM_Str) );
   }
-  u.bh.seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bh.pC->seekResult : 0);
-  if( u.bh.pData->flags & MEM_Zero ){
-    u.bh.nZero = u.bh.pData->u.nZero;
+  u.bi.seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bi.pC->seekResult : 0);
+  if( u.bi.pData->flags & MEM_Zero ){
+    u.bi.nZero = u.bi.pData->u.nZero;
   }else{
-    u.bh.nZero = 0;
+    u.bi.nZero = 0;
   }
-  sqlite3BtreeSetCachedRowid(u.bh.pC->pCursor, 0);
-  rc = sqlite3BtreeInsert(u.bh.pC->pCursor, 0, u.bh.iKey,
-                          u.bh.pData->z, u.bh.pData->n, u.bh.nZero,
-                          pOp->p5 & OPFLAG_APPEND, u.bh.seekResult
+  sqlite3BtreeSetCachedRowid(u.bi.pC->pCursor, 0);
+  rc = sqlite3BtreeInsert(u.bi.pC->pCursor, 0, u.bi.iKey,
+                          u.bi.pData->z, u.bi.pData->n, u.bi.nZero,
+                          pOp->p5 & OPFLAG_APPEND, u.bi.seekResult
   );
-  u.bh.pC->rowidIsValid = 0;
-  u.bh.pC->deferredMoveto = 0;
-  u.bh.pC->cacheStatus = CACHE_STALE;
+  u.bi.pC->rowidIsValid = 0;
+  u.bi.pC->deferredMoveto = 0;
+  u.bi.pC->cacheStatus = CACHE_STALE;
 
   /* Invoke the update-hook if required. */
   if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
-    u.bh.zDb = db->aDb[u.bh.pC->iDb].zName;
-    u.bh.zTbl = pOp->p4.z;
-    u.bh.op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
-    assert( u.bh.pC->isTable );
-    db->xUpdateCallback(db->pUpdateArg, u.bh.op, u.bh.zDb, u.bh.zTbl, u.bh.iKey);
-    assert( u.bh.pC->iDb>=0 );
+    u.bi.zDb = db->aDb[u.bi.pC->iDb].zName;
+    u.bi.zTbl = pOp->p4.z;
+    u.bi.op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
+    assert( u.bi.pC->isTable );
+    db->xUpdateCallback(db->pUpdateArg, u.bi.op, u.bi.zDb, u.bi.zTbl, u.bi.iKey);
+    assert( u.bi.pC->iDb>=0 );
   }
   break;
 }
@@ -69878,47 +68116,47 @@ case OP_InsertInt: {
 ** using OP_NotFound prior to invoking this opcode.
 */
 case OP_Delete: {
-#if 0  /* local variables moved into u.bi */
+#if 0  /* local variables moved into u.bj */
   i64 iKey;
   VdbeCursor *pC;
-#endif /* local variables moved into u.bi */
+#endif /* local variables moved into u.bj */
 
-  u.bi.iKey = 0;
+  u.bj.iKey = 0;
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
-  u.bi.pC = p->apCsr[pOp->p1];
-  assert( u.bi.pC!=0 );
-  assert( u.bi.pC->pCursor!=0 );  /* Only valid for real tables, no pseudotables */
+  u.bj.pC = p->apCsr[pOp->p1];
+  assert( u.bj.pC!=0 );
+  assert( u.bj.pC->pCursor!=0 );  /* Only valid for real tables, no pseudotables */
 
-  /* If the update-hook will be invoked, set u.bi.iKey to the rowid of the
+  /* If the update-hook will be invoked, set u.bj.iKey to the rowid of the
   ** row being deleted.
   */
   if( db->xUpdateCallback && pOp->p4.z ){
-    assert( u.bi.pC->isTable );
-    assert( u.bi.pC->rowidIsValid );  /* lastRowid set by previous OP_NotFound */
-    u.bi.iKey = u.bi.pC->lastRowid;
+    assert( u.bj.pC->isTable );
+    assert( u.bj.pC->rowidIsValid );  /* lastRowid set by previous OP_NotFound */
+    u.bj.iKey = u.bj.pC->lastRowid;
   }
 
   /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or
   ** OP_Column on the same table without any intervening operations that
-  ** might move or invalidate the cursor.  Hence cursor u.bi.pC is always pointing
+  ** might move or invalidate the cursor.  Hence cursor u.bj.pC is always pointing
   ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation
   ** below is always a no-op and cannot fail.  We will run it anyhow, though,
   ** to guard against future changes to the code generator.
   **/
-  assert( u.bi.pC->deferredMoveto==0 );
-  rc = sqlite3VdbeCursorMoveto(u.bi.pC);
+  assert( u.bj.pC->deferredMoveto==0 );
+  rc = sqlite3VdbeCursorMoveto(u.bj.pC);
   if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
 
-  sqlite3BtreeSetCachedRowid(u.bi.pC->pCursor, 0);
-  rc = sqlite3BtreeDelete(u.bi.pC->pCursor);
-  u.bi.pC->cacheStatus = CACHE_STALE;
+  sqlite3BtreeSetCachedRowid(u.bj.pC->pCursor, 0);
+  rc = sqlite3BtreeDelete(u.bj.pC->pCursor);
+  u.bj.pC->cacheStatus = CACHE_STALE;
 
   /* Invoke the update-hook if required. */
   if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
-    const char *zDb = db->aDb[u.bi.pC->iDb].zName;
+    const char *zDb = db->aDb[u.bj.pC->iDb].zName;
     const char *zTbl = pOp->p4.z;
-    db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bi.iKey);
-    assert( u.bi.pC->iDb>=0 );
+    db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bj.iKey);
+    assert( u.bj.pC->iDb>=0 );
   }
   if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
   break;
@@ -69944,16 +68182,16 @@ case OP_ResetCount: {
 ** fall through to the next instruction. Otherwise, jump to instruction P2.
 */
 case OP_SorterCompare: {
-#if 0  /* local variables moved into u.bj */
+#if 0  /* local variables moved into u.bk */
   VdbeCursor *pC;
   int res;
-#endif /* local variables moved into u.bj */
+#endif /* local variables moved into u.bk */
 
-  u.bj.pC = p->apCsr[pOp->p1];
-  assert( isSorter(u.bj.pC) );
+  u.bk.pC = p->apCsr[pOp->p1];
+  assert( isSorter(u.bk.pC) );
   pIn3 = &aMem[pOp->p3];
-  rc = sqlite3VdbeSorterCompare(u.bj.pC, pIn3, &u.bj.res);
-  if( u.bj.res ){
+  rc = sqlite3VdbeSorterCompare(u.bk.pC, pIn3, &u.bk.res);
+  if( u.bk.res ){
     pc = pOp->p2-1;
   }
   break;
@@ -69964,14 +68202,15 @@ case OP_SorterCompare: {
 ** Write into register P2 the current sorter data for sorter cursor P1.
 */
 case OP_SorterData: {
-#if 0  /* local variables moved into u.bk */
+#if 0  /* local variables moved into u.bl */
   VdbeCursor *pC;
-#endif /* local variables moved into u.bk */
+#endif /* local variables moved into u.bl */
+
 #ifndef SQLITE_OMIT_MERGE_SORT
   pOut = &aMem[pOp->p2];
-  u.bk.pC = p->apCsr[pOp->p1];
-  assert( u.bk.pC->isSorter );
-  rc = sqlite3VdbeSorterRowkey(u.bk.pC, pOut);
+  u.bl.pC = p->apCsr[pOp->p1];
+  assert( u.bl.pC->isSorter );
+  rc = sqlite3VdbeSorterRowkey(u.bl.pC, pOut);
 #else
   pOp->opcode = OP_RowKey;
   pc--;
@@ -70001,62 +68240,62 @@ case OP_SorterData: {
 */
 case OP_RowKey:
 case OP_RowData: {
-#if 0  /* local variables moved into u.bl */
+#if 0  /* local variables moved into u.bm */
   VdbeCursor *pC;
   BtCursor *pCrsr;
   u32 n;
   i64 n64;
-#endif /* local variables moved into u.bl */
+#endif /* local variables moved into u.bm */
 
   pOut = &aMem[pOp->p2];
   memAboutToChange(p, pOut);
 
   /* Note that RowKey and RowData are really exactly the same instruction */
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
-  u.bl.pC = p->apCsr[pOp->p1];
-  assert( u.bl.pC->isSorter==0 );
-  assert( u.bl.pC->isTable || pOp->opcode!=OP_RowData );
-  assert( u.bl.pC->isIndex || pOp->opcode==OP_RowData );
-  assert( u.bl.pC!=0 );
-  assert( u.bl.pC->nullRow==0 );
-  assert( u.bl.pC->pseudoTableReg==0 );
-  assert( u.bl.pC->pCursor!=0 );
-  u.bl.pCrsr = u.bl.pC->pCursor;
-  assert( sqlite3BtreeCursorIsValid(u.bl.pCrsr) );
+  u.bm.pC = p->apCsr[pOp->p1];
+  assert( u.bm.pC->isSorter==0 );
+  assert( u.bm.pC->isTable || pOp->opcode!=OP_RowData );
+  assert( u.bm.pC->isIndex || pOp->opcode==OP_RowData );
+  assert( u.bm.pC!=0 );
+  assert( u.bm.pC->nullRow==0 );
+  assert( u.bm.pC->pseudoTableReg==0 );
+  assert( u.bm.pC->pCursor!=0 );
+  u.bm.pCrsr = u.bm.pC->pCursor;
+  assert( sqlite3BtreeCursorIsValid(u.bm.pCrsr) );
 
   /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or
   ** OP_Rewind/Op_Next with no intervening instructions that might invalidate
   ** the cursor.  Hence the following sqlite3VdbeCursorMoveto() call is always
   ** a no-op and can never fail.  But we leave it in place as a safety.
   */
-  assert( u.bl.pC->deferredMoveto==0 );
-  rc = sqlite3VdbeCursorMoveto(u.bl.pC);
+  assert( u.bm.pC->deferredMoveto==0 );
+  rc = sqlite3VdbeCursorMoveto(u.bm.pC);
   if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
 
-  if( u.bl.pC->isIndex ){
-    assert( !u.bl.pC->isTable );
-    VVA_ONLY(rc =) sqlite3BtreeKeySize(u.bl.pCrsr, &u.bl.n64);
+  if( u.bm.pC->isIndex ){
+    assert( !u.bm.pC->isTable );
+    VVA_ONLY(rc =) sqlite3BtreeKeySize(u.bm.pCrsr, &u.bm.n64);
     assert( rc==SQLITE_OK );    /* True because of CursorMoveto() call above */
-    if( u.bl.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+    if( u.bm.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
       goto too_big;
     }
-    u.bl.n = (u32)u.bl.n64;
+    u.bm.n = (u32)u.bm.n64;
   }else{
-    VVA_ONLY(rc =) sqlite3BtreeDataSize(u.bl.pCrsr, &u.bl.n);
+    VVA_ONLY(rc =) sqlite3BtreeDataSize(u.bm.pCrsr, &u.bm.n);
     assert( rc==SQLITE_OK );    /* DataSize() cannot fail */
-    if( u.bl.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
+    if( u.bm.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
       goto too_big;
     }
   }
-  if( sqlite3VdbeMemGrow(pOut, u.bl.n, 0) ){
+  if( sqlite3VdbeMemGrow(pOut, u.bm.n, 0) ){
     goto no_mem;
   }
-  pOut->n = u.bl.n;
+  pOut->n = u.bm.n;
   MemSetTypeFlag(pOut, MEM_Blob);
-  if( u.bl.pC->isIndex ){
-    rc = sqlite3BtreeKey(u.bl.pCrsr, 0, u.bl.n, pOut->z);
+  if( u.bm.pC->isIndex ){
+    rc = sqlite3BtreeKey(u.bm.pCrsr, 0, u.bm.n, pOut->z);
   }else{
-    rc = sqlite3BtreeData(u.bl.pCrsr, 0, u.bl.n, pOut->z);
+    rc = sqlite3BtreeData(u.bm.pCrsr, 0, u.bm.n, pOut->z);
   }
   pOut->enc = SQLITE_UTF8;  /* In case the blob is ever cast to text */
   UPDATE_MAX_BLOBSIZE(pOut);
@@ -70073,42 +68312,42 @@ case OP_RowData: {
 ** one opcode now works for both table types.
 */
 case OP_Rowid: {                 /* out2-prerelease */
-#if 0  /* local variables moved into u.bm */
+#if 0  /* local variables moved into u.bn */
   VdbeCursor *pC;
   i64 v;
   sqlite3_vtab *pVtab;
   const sqlite3_module *pModule;
-#endif /* local variables moved into u.bm */
+#endif /* local variables moved into u.bn */
 
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
-  u.bm.pC = p->apCsr[pOp->p1];
-  assert( u.bm.pC!=0 );
-  assert( u.bm.pC->pseudoTableReg==0 );
-  if( u.bm.pC->nullRow ){
+  u.bn.pC = p->apCsr[pOp->p1];
+  assert( u.bn.pC!=0 );
+  assert( u.bn.pC->pseudoTableReg==0 || u.bn.pC->nullRow );
+  if( u.bn.pC->nullRow ){
     pOut->flags = MEM_Null;
     break;
-  }else if( u.bm.pC->deferredMoveto ){
-    u.bm.v = u.bm.pC->movetoTarget;
+  }else if( u.bn.pC->deferredMoveto ){
+    u.bn.v = u.bn.pC->movetoTarget;
 #ifndef SQLITE_OMIT_VIRTUALTABLE
-  }else if( u.bm.pC->pVtabCursor ){
-    u.bm.pVtab = u.bm.pC->pVtabCursor->pVtab;
-    u.bm.pModule = u.bm.pVtab->pModule;
-    assert( u.bm.pModule->xRowid );
-    rc = u.bm.pModule->xRowid(u.bm.pC->pVtabCursor, &u.bm.v);
-    importVtabErrMsg(p, u.bm.pVtab);
+  }else if( u.bn.pC->pVtabCursor ){
+    u.bn.pVtab = u.bn.pC->pVtabCursor->pVtab;
+    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);
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
   }else{
-    assert( u.bm.pC->pCursor!=0 );
-    rc = sqlite3VdbeCursorMoveto(u.bm.pC);
+    assert( u.bn.pC->pCursor!=0 );
+    rc = sqlite3VdbeCursorMoveto(u.bn.pC);
     if( rc ) goto abort_due_to_error;
-    if( u.bm.pC->rowidIsValid ){
-      u.bm.v = u.bm.pC->lastRowid;
+    if( u.bn.pC->rowidIsValid ){
+      u.bn.v = u.bn.pC->lastRowid;
     }else{
-      rc = sqlite3BtreeKeySize(u.bm.pC->pCursor, &u.bm.v);
+      rc = sqlite3BtreeKeySize(u.bn.pC->pCursor, &u.bn.v);
       assert( rc==SQLITE_OK );  /* Always so because of CursorMoveto() above */
     }
   }
-  pOut->u.i = u.bm.v;
+  pOut->u.i = u.bn.v;
   break;
 }
 
@@ -70119,18 +68358,18 @@ case OP_Rowid: {                 /* out2-prerelease */
 ** write a NULL.
 */
 case OP_NullRow: {
-#if 0  /* local variables moved into u.bn */
+#if 0  /* local variables moved into u.bo */
   VdbeCursor *pC;
-#endif /* local variables moved into u.bn */
+#endif /* local variables moved into u.bo */
 
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
-  u.bn.pC = p->apCsr[pOp->p1];
-  assert( u.bn.pC!=0 );
-  u.bn.pC->nullRow = 1;
-  u.bn.pC->rowidIsValid = 0;
-  assert( u.bn.pC->pCursor || u.bn.pC->pVtabCursor );
-  if( u.bn.pC->pCursor ){
-    sqlite3BtreeClearCursor(u.bn.pC->pCursor);
+  u.bo.pC = p->apCsr[pOp->p1];
+  assert( u.bo.pC!=0 );
+  u.bo.pC->nullRow = 1;
+  u.bo.pC->rowidIsValid = 0;
+  assert( u.bo.pC->pCursor || u.bo.pC->pVtabCursor );
+  if( u.bo.pC->pCursor ){
+    sqlite3BtreeClearCursor(u.bo.pC->pCursor);
   }
   break;
 }
@@ -70144,25 +68383,25 @@ case OP_NullRow: {
 ** to the following instruction.
 */
 case OP_Last: {        /* jump */
-#if 0  /* local variables moved into u.bo */
+#if 0  /* local variables moved into u.bp */
   VdbeCursor *pC;
   BtCursor *pCrsr;
   int res;
-#endif /* local variables moved into u.bo */
+#endif /* local variables moved into u.bp */
 
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
-  u.bo.pC = p->apCsr[pOp->p1];
-  assert( u.bo.pC!=0 );
-  u.bo.pCrsr = u.bo.pC->pCursor;
-  u.bo.res = 0;
-  if( ALWAYS(u.bo.pCrsr!=0) ){
-    rc = sqlite3BtreeLast(u.bo.pCrsr, &u.bo.res);
+  u.bp.pC = p->apCsr[pOp->p1];
+  assert( u.bp.pC!=0 );
+  u.bp.pCrsr = u.bp.pC->pCursor;
+  u.bp.res = 0;
+  if( ALWAYS(u.bp.pCrsr!=0) ){
+    rc = sqlite3BtreeLast(u.bp.pCrsr, &u.bp.res);
   }
-  u.bo.pC->nullRow = (u8)u.bo.res;
-  u.bo.pC->deferredMoveto = 0;
-  u.bo.pC->rowidIsValid = 0;
-  u.bo.pC->cacheStatus = CACHE_STALE;
-  if( pOp->p2>0 && u.bo.res ){
+  u.bp.pC->nullRow = (u8)u.bp.res;
+  u.bp.pC->deferredMoveto = 0;
+  u.bp.pC->rowidIsValid = 0;
+  u.bp.pC->cacheStatus = CACHE_STALE;
+  if( pOp->p2>0 && u.bp.res ){
     pc = pOp->p2 - 1;
   }
   break;
@@ -70202,31 +68441,31 @@ case OP_Sort: {        /* jump */
 ** to the following instruction.
 */
 case OP_Rewind: {        /* jump */
-#if 0  /* local variables moved into u.bp */
+#if 0  /* local variables moved into u.bq */
   VdbeCursor *pC;
   BtCursor *pCrsr;
   int res;
-#endif /* local variables moved into u.bp */
+#endif /* local variables moved into u.bq */
 
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
-  u.bp.pC = p->apCsr[pOp->p1];
-  assert( u.bp.pC!=0 );
-  assert( u.bp.pC->isSorter==(pOp->opcode==OP_SorterSort) );
-  u.bp.res = 1;
-  if( isSorter(u.bp.pC) ){
-    rc = sqlite3VdbeSorterRewind(db, u.bp.pC, &u.bp.res);
-  }else{
-    u.bp.pCrsr = u.bp.pC->pCursor;
-    assert( u.bp.pCrsr );
-    rc = sqlite3BtreeFirst(u.bp.pCrsr, &u.bp.res);
-    u.bp.pC->atFirst = u.bp.res==0 ?1:0;
-    u.bp.pC->deferredMoveto = 0;
-    u.bp.pC->cacheStatus = CACHE_STALE;
-    u.bp.pC->rowidIsValid = 0;
+  u.bq.pC = p->apCsr[pOp->p1];
+  assert( u.bq.pC!=0 );
+  assert( u.bq.pC->isSorter==(pOp->opcode==OP_SorterSort) );
+  u.bq.res = 1;
+  if( isSorter(u.bq.pC) ){
+    rc = sqlite3VdbeSorterRewind(db, u.bq.pC, &u.bq.res);
+  }else{
+    u.bq.pCrsr = u.bq.pC->pCursor;
+    assert( u.bq.pCrsr );
+    rc = sqlite3BtreeFirst(u.bq.pCrsr, &u.bq.res);
+    u.bq.pC->atFirst = u.bq.res==0 ?1:0;
+    u.bq.pC->deferredMoveto = 0;
+    u.bq.pC->cacheStatus = CACHE_STALE;
+    u.bq.pC->rowidIsValid = 0;
   }
-  u.bp.pC->nullRow = (u8)u.bp.res;
+  u.bq.pC->nullRow = (u8)u.bq.res;
   assert( pOp->p2>0 && pOp->p2<p->nOp );
-  if( u.bp.res ){
+  if( u.bq.res ){
     pc = pOp->p2 - 1;
   }
   break;
@@ -70270,40 +68509,40 @@ case OP_SorterNext:    /* jump */
 #endif
 case OP_Prev:          /* jump */
 case OP_Next: {        /* jump */
-#if 0  /* local variables moved into u.bq */
+#if 0  /* local variables moved into u.br */
   VdbeCursor *pC;
   int res;
-#endif /* local variables moved into u.bq */
+#endif /* local variables moved into u.br */
 
   CHECK_FOR_INTERRUPT;
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
   assert( pOp->p5<=ArraySize(p->aCounter) );
-  u.bq.pC = p->apCsr[pOp->p1];
-  if( u.bq.pC==0 ){
+  u.br.pC = p->apCsr[pOp->p1];
+  if( u.br.pC==0 ){
     break;  /* See ticket #2273 */
   }
-  assert( u.bq.pC->isSorter==(pOp->opcode==OP_SorterNext) );
-  if( isSorter(u.bq.pC) ){
+  assert( u.br.pC->isSorter==(pOp->opcode==OP_SorterNext) );
+  if( isSorter(u.br.pC) ){
     assert( pOp->opcode==OP_SorterNext );
-    rc = sqlite3VdbeSorterNext(db, u.bq.pC, &u.bq.res);
+    rc = sqlite3VdbeSorterNext(db, u.br.pC, &u.br.res);
   }else{
-    u.bq.res = 1;
-    assert( u.bq.pC->deferredMoveto==0 );
-    assert( u.bq.pC->pCursor );
+    u.br.res = 1;
+    assert( u.br.pC->deferredMoveto==0 );
+    assert( u.br.pC->pCursor );
     assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext );
     assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious );
-    rc = pOp->p4.xAdvance(u.bq.pC->pCursor, &u.bq.res);
+    rc = pOp->p4.xAdvance(u.br.pC->pCursor, &u.br.res);
   }
-  u.bq.pC->nullRow = (u8)u.bq.res;
-  u.bq.pC->cacheStatus = CACHE_STALE;
-  if( u.bq.res==0 ){
+  u.br.pC->nullRow = (u8)u.br.res;
+  u.br.pC->cacheStatus = CACHE_STALE;
+  if( u.br.res==0 ){
     pc = pOp->p2 - 1;
     if( pOp->p5 ) p->aCounter[pOp->p5-1]++;
 #ifdef SQLITE_TEST
     sqlite3_search_count++;
 #endif
   }
-  u.bq.pC->rowidIsValid = 0;
+  u.br.pC->rowidIsValid = 0;
   break;
 }
 
@@ -70324,34 +68563,34 @@ case OP_SorterInsert:       /* in2 */
   pOp->opcode = OP_IdxInsert;
 #endif
 case OP_IdxInsert: {        /* in2 */
-#if 0  /* local variables moved into u.br */
+#if 0  /* local variables moved into u.bs */
   VdbeCursor *pC;
   BtCursor *pCrsr;
   int nKey;
   const char *zKey;
-#endif /* local variables moved into u.br */
+#endif /* local variables moved into u.bs */
 
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
-  u.br.pC = p->apCsr[pOp->p1];
-  assert( u.br.pC!=0 );
-  assert( u.br.pC->isSorter==(pOp->opcode==OP_SorterInsert) );
+  u.bs.pC = p->apCsr[pOp->p1];
+  assert( u.bs.pC!=0 );
+  assert( u.bs.pC->isSorter==(pOp->opcode==OP_SorterInsert) );
   pIn2 = &aMem[pOp->p2];
   assert( pIn2->flags & MEM_Blob );
-  u.br.pCrsr = u.br.pC->pCursor;
-  if( ALWAYS(u.br.pCrsr!=0) ){
-    assert( u.br.pC->isTable==0 );
+  u.bs.pCrsr = u.bs.pC->pCursor;
+  if( ALWAYS(u.bs.pCrsr!=0) ){
+    assert( u.bs.pC->isTable==0 );
     rc = ExpandBlob(pIn2);
     if( rc==SQLITE_OK ){
-      if( isSorter(u.br.pC) ){
-        rc = sqlite3VdbeSorterWrite(db, u.br.pC, pIn2);
+      if( isSorter(u.bs.pC) ){
+        rc = sqlite3VdbeSorterWrite(db, u.bs.pC, pIn2);
       }else{
-        u.br.nKey = pIn2->n;
-        u.br.zKey = pIn2->z;
-        rc = sqlite3BtreeInsert(u.br.pCrsr, u.br.zKey, u.br.nKey, "", 0, 0, pOp->p3,
-            ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.br.pC->seekResult : 0)
+        u.bs.nKey = pIn2->n;
+        u.bs.zKey = pIn2->z;
+        rc = sqlite3BtreeInsert(u.bs.pCrsr, u.bs.zKey, u.bs.nKey, "", 0, 0, pOp->p3,
+            ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bs.pC->seekResult : 0)
             );
-        assert( u.br.pC->deferredMoveto==0 );
-        u.br.pC->cacheStatus = CACHE_STALE;
+        assert( u.bs.pC->deferredMoveto==0 );
+        u.bs.pC->cacheStatus = CACHE_STALE;
       }
     }
   }
@@ -70365,33 +68604,33 @@ case OP_IdxInsert: {        /* in2 */
 ** index opened by cursor P1.
 */
 case OP_IdxDelete: {
-#if 0  /* local variables moved into u.bs */
+#if 0  /* local variables moved into u.bt */
   VdbeCursor *pC;
   BtCursor *pCrsr;
   int res;
   UnpackedRecord r;
-#endif /* local variables moved into u.bs */
+#endif /* local variables moved into u.bt */
 
   assert( pOp->p3>0 );
   assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 );
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
-  u.bs.pC = p->apCsr[pOp->p1];
-  assert( u.bs.pC!=0 );
-  u.bs.pCrsr = u.bs.pC->pCursor;
-  if( ALWAYS(u.bs.pCrsr!=0) ){
-    u.bs.r.pKeyInfo = u.bs.pC->pKeyInfo;
-    u.bs.r.nField = (u16)pOp->p3;
-    u.bs.r.flags = 0;
-    u.bs.r.aMem = &aMem[pOp->p2];
+  u.bt.pC = p->apCsr[pOp->p1];
+  assert( u.bt.pC!=0 );
+  u.bt.pCrsr = u.bt.pC->pCursor;
+  if( ALWAYS(u.bt.pCrsr!=0) ){
+    u.bt.r.pKeyInfo = u.bt.pC->pKeyInfo;
+    u.bt.r.nField = (u16)pOp->p3;
+    u.bt.r.flags = 0;
+    u.bt.r.aMem = &aMem[pOp->p2];
 #ifdef SQLITE_DEBUG
-    { int i; for(i=0; i<u.bs.r.nField; i++) assert( memIsValid(&u.bs.r.aMem[i]) ); }
+    { int i; for(i=0; i<u.bt.r.nField; i++) assert( memIsValid(&u.bt.r.aMem[i]) ); }
 #endif
-    rc = sqlite3BtreeMovetoUnpacked(u.bs.pCrsr, &u.bs.r, 0, 0, &u.bs.res);
-    if( rc==SQLITE_OK && u.bs.res==0 ){
-      rc = sqlite3BtreeDelete(u.bs.pCrsr);
+    rc = sqlite3BtreeMovetoUnpacked(u.bt.pCrsr, &u.bt.r, 0, 0, &u.bt.res);
+    if( rc==SQLITE_OK && u.bt.res==0 ){
+      rc = sqlite3BtreeDelete(u.bt.pCrsr);
     }
-    assert( u.bs.pC->deferredMoveto==0 );
-    u.bs.pC->cacheStatus = CACHE_STALE;
+    assert( u.bt.pC->deferredMoveto==0 );
+    u.bt.pC->cacheStatus = CACHE_STALE;
   }
   break;
 }
@@ -70405,28 +68644,28 @@ case OP_IdxDelete: {
 ** See also: Rowid, MakeRecord.
 */
 case OP_IdxRowid: {              /* out2-prerelease */
-#if 0  /* local variables moved into u.bt */
+#if 0  /* local variables moved into u.bu */
   BtCursor *pCrsr;
   VdbeCursor *pC;
   i64 rowid;
-#endif /* local variables moved into u.bt */
+#endif /* local variables moved into u.bu */
 
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
-  u.bt.pC = p->apCsr[pOp->p1];
-  assert( u.bt.pC!=0 );
-  u.bt.pCrsr = u.bt.pC->pCursor;
+  u.bu.pC = p->apCsr[pOp->p1];
+  assert( u.bu.pC!=0 );
+  u.bu.pCrsr = u.bu.pC->pCursor;
   pOut->flags = MEM_Null;
-  if( ALWAYS(u.bt.pCrsr!=0) ){
-    rc = sqlite3VdbeCursorMoveto(u.bt.pC);
+  if( ALWAYS(u.bu.pCrsr!=0) ){
+    rc = sqlite3VdbeCursorMoveto(u.bu.pC);
     if( NEVER(rc) ) goto abort_due_to_error;
-    assert( u.bt.pC->deferredMoveto==0 );
-    assert( u.bt.pC->isTable==0 );
-    if( !u.bt.pC->nullRow ){
-      rc = sqlite3VdbeIdxRowid(db, u.bt.pCrsr, &u.bt.rowid);
+    assert( u.bu.pC->deferredMoveto==0 );
+    assert( u.bu.pC->isTable==0 );
+    if( !u.bu.pC->nullRow ){
+      rc = sqlite3VdbeIdxRowid(db, u.bu.pCrsr, &u.bu.rowid);
       if( rc!=SQLITE_OK ){
         goto abort_due_to_error;
       }
-      pOut->u.i = u.bt.rowid;
+      pOut->u.i = u.bu.rowid;
       pOut->flags = MEM_Int;
     }
   }
@@ -70461,39 +68700,39 @@ case OP_IdxRowid: {              /* out2-prerelease */
 */
 case OP_IdxLT:          /* jump */
 case OP_IdxGE: {        /* jump */
-#if 0  /* local variables moved into u.bu */
+#if 0  /* local variables moved into u.bv */
   VdbeCursor *pC;
   int res;
   UnpackedRecord r;
-#endif /* local variables moved into u.bu */
+#endif /* local variables moved into u.bv */
 
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
-  u.bu.pC = p->apCsr[pOp->p1];
-  assert( u.bu.pC!=0 );
-  assert( u.bu.pC->isOrdered );
-  if( ALWAYS(u.bu.pC->pCursor!=0) ){
-    assert( u.bu.pC->deferredMoveto==0 );
+  u.bv.pC = p->apCsr[pOp->p1];
+  assert( u.bv.pC!=0 );
+  assert( u.bv.pC->isOrdered );
+  if( ALWAYS(u.bv.pC->pCursor!=0) ){
+    assert( u.bv.pC->deferredMoveto==0 );
     assert( pOp->p5==0 || pOp->p5==1 );
     assert( pOp->p4type==P4_INT32 );
-    u.bu.r.pKeyInfo = u.bu.pC->pKeyInfo;
-    u.bu.r.nField = (u16)pOp->p4.i;
+    u.bv.r.pKeyInfo = u.bv.pC->pKeyInfo;
+    u.bv.r.nField = (u16)pOp->p4.i;
     if( pOp->p5 ){
-      u.bu.r.flags = UNPACKED_INCRKEY | UNPACKED_PREFIX_MATCH;
+      u.bv.r.flags = UNPACKED_INCRKEY | UNPACKED_PREFIX_MATCH;
     }else{
-      u.bu.r.flags = UNPACKED_PREFIX_MATCH;
+      u.bv.r.flags = UNPACKED_PREFIX_MATCH;
     }
-    u.bu.r.aMem = &aMem[pOp->p3];
+    u.bv.r.aMem = &aMem[pOp->p3];
 #ifdef SQLITE_DEBUG
-    { int i; for(i=0; i<u.bu.r.nField; i++) assert( memIsValid(&u.bu.r.aMem[i]) ); }
+    { int i; for(i=0; i<u.bv.r.nField; i++) assert( memIsValid(&u.bv.r.aMem[i]) ); }
 #endif
-    rc = sqlite3VdbeIdxKeyCompare(u.bu.pC, &u.bu.r, &u.bu.res);
+    rc = sqlite3VdbeIdxKeyCompare(u.bv.pC, &u.bv.r, &u.bv.res);
     if( pOp->opcode==OP_IdxLT ){
-      u.bu.res = -u.bu.res;
+      u.bv.res = -u.bv.res;
     }else{
       assert( pOp->opcode==OP_IdxGE );
-      u.bu.res++;
+      u.bv.res++;
     }
-    if( u.bu.res>0 ){
+    if( u.bv.res>0 ){
       pc = pOp->p2 - 1 ;
     }
   }
@@ -70521,39 +68760,40 @@ case OP_IdxGE: {        /* jump */
 ** See also: Clear
 */
 case OP_Destroy: {     /* out2-prerelease */
-#if 0  /* local variables moved into u.bv */
+#if 0  /* local variables moved into u.bw */
   int iMoved;
   int iCnt;
   Vdbe *pVdbe;
   int iDb;
-#endif /* local variables moved into u.bv */
+#endif /* local variables moved into u.bw */
+
 #ifndef SQLITE_OMIT_VIRTUALTABLE
-  u.bv.iCnt = 0;
-  for(u.bv.pVdbe=db->pVdbe; u.bv.pVdbe; u.bv.pVdbe = u.bv.pVdbe->pNext){
-    if( u.bv.pVdbe->magic==VDBE_MAGIC_RUN && u.bv.pVdbe->inVtabMethod<2 && u.bv.pVdbe->pc>=0 ){
-      u.bv.iCnt++;
+  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 ){
+      u.bw.iCnt++;
     }
   }
 #else
-  u.bv.iCnt = db->activeVdbeCnt;
+  u.bw.iCnt = db->activeVdbeCnt;
 #endif
   pOut->flags = MEM_Null;
-  if( u.bv.iCnt>1 ){
+  if( u.bw.iCnt>1 ){
     rc = SQLITE_LOCKED;
     p->errorAction = OE_Abort;
   }else{
-    u.bv.iDb = pOp->p3;
-    assert( u.bv.iCnt==1 );
-    assert( (p->btreeMask & (((yDbMask)1)<<u.bv.iDb))!=0 );
-    rc = sqlite3BtreeDropTable(db->aDb[u.bv.iDb].pBt, pOp->p1, &u.bv.iMoved);
+    u.bw.iDb = pOp->p3;
+    assert( u.bw.iCnt==1 );
+    assert( (p->btreeMask & (((yDbMask)1)<<u.bw.iDb))!=0 );
+    rc = sqlite3BtreeDropTable(db->aDb[u.bw.iDb].pBt, pOp->p1, &u.bw.iMoved);
     pOut->flags = MEM_Int;
-    pOut->u.i = u.bv.iMoved;
+    pOut->u.i = u.bw.iMoved;
 #ifndef SQLITE_OMIT_AUTOVACUUM
-    if( rc==SQLITE_OK && u.bv.iMoved!=0 ){
-      sqlite3RootPageMoved(db, u.bv.iDb, u.bv.iMoved, pOp->p1);
+    if( rc==SQLITE_OK && u.bw.iMoved!=0 ){
+      sqlite3RootPageMoved(db, u.bw.iDb, u.bw.iMoved, pOp->p1);
       /* All OP_Destroy operations occur on the same btree */
-      assert( resetSchemaOnFault==0 || resetSchemaOnFault==u.bv.iDb+1 );
-      resetSchemaOnFault = u.bv.iDb+1;
+      assert( resetSchemaOnFault==0 || resetSchemaOnFault==u.bw.iDb+1 );
+      resetSchemaOnFault = u.bw.iDb+1;
     }
 #endif
   }
@@ -70579,21 +68819,21 @@ case OP_Destroy: {     /* out2-prerelease */
 ** See also: Destroy
 */
 case OP_Clear: {
-#if 0  /* local variables moved into u.bw */
+#if 0  /* local variables moved into u.bx */
   int nChange;
-#endif /* local variables moved into u.bw */
+#endif /* local variables moved into u.bx */
 
-  u.bw.nChange = 0;
+  u.bx.nChange = 0;
   assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 );
   rc = sqlite3BtreeClearTable(
-      db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bw.nChange : 0)
+      db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bx.nChange : 0)
   );
   if( pOp->p3 ){
-    p->nChange += u.bw.nChange;
+    p->nChange += u.bx.nChange;
     if( pOp->p3>0 ){
       assert( memIsValid(&aMem[pOp->p3]) );
       memAboutToChange(p, &aMem[pOp->p3]);
-      aMem[pOp->p3].u.i += u.bw.nChange;
+      aMem[pOp->p3].u.i += u.bx.nChange;
     }
   }
   break;
@@ -70623,25 +68863,25 @@ case OP_Clear: {
 */
 case OP_CreateIndex:            /* out2-prerelease */
 case OP_CreateTable: {          /* out2-prerelease */
-#if 0  /* local variables moved into u.bx */
+#if 0  /* local variables moved into u.by */
   int pgno;
   int flags;
   Db *pDb;
-#endif /* local variables moved into u.bx */
+#endif /* local variables moved into u.by */
 
-  u.bx.pgno = 0;
+  u.by.pgno = 0;
   assert( pOp->p1>=0 && pOp->p1<db->nDb );
   assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
-  u.bx.pDb = &db->aDb[pOp->p1];
-  assert( u.bx.pDb->pBt!=0 );
+  u.by.pDb = &db->aDb[pOp->p1];
+  assert( u.by.pDb->pBt!=0 );
   if( pOp->opcode==OP_CreateTable ){
-    /* u.bx.flags = BTREE_INTKEY; */
-    u.bx.flags = BTREE_INTKEY;
+    /* u.by.flags = BTREE_INTKEY; */
+    u.by.flags = BTREE_INTKEY;
   }else{
-    u.bx.flags = BTREE_BLOBKEY;
+    u.by.flags = BTREE_BLOBKEY;
   }
-  rc = sqlite3BtreeCreateTable(u.bx.pDb->pBt, &u.bx.pgno, u.bx.flags);
-  pOut->u.i = u.bx.pgno;
+  rc = sqlite3BtreeCreateTable(u.by.pDb->pBt, &u.by.pgno, u.by.flags);
+  pOut->u.i = u.by.pgno;
   break;
 }
 
@@ -70654,44 +68894,44 @@ case OP_CreateTable: {          /* out2-prerelease */
 ** then runs the new virtual machine.  It is thus a re-entrant opcode.
 */
 case OP_ParseSchema: {
-#if 0  /* local variables moved into u.by */
+#if 0  /* local variables moved into u.bz */
   int iDb;
   const char *zMaster;
   char *zSql;
   InitData initData;
-#endif /* local variables moved into u.by */
+#endif /* local variables moved into u.bz */
 
   /* Any prepared statement that invokes this opcode will hold mutexes
   ** on every btree.  This is a prerequisite for invoking
   ** sqlite3InitCallback().
   */
 #ifdef SQLITE_DEBUG
-  for(u.by.iDb=0; u.by.iDb<db->nDb; u.by.iDb++){
-    assert( u.by.iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[u.by.iDb].pBt) );
+  for(u.bz.iDb=0; u.bz.iDb<db->nDb; u.bz.iDb++){
+    assert( u.bz.iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[u.bz.iDb].pBt) );
   }
 #endif
 
-  u.by.iDb = pOp->p1;
-  assert( u.by.iDb>=0 && u.by.iDb<db->nDb );
-  assert( DbHasProperty(db, u.by.iDb, DB_SchemaLoaded) );
+  u.bz.iDb = pOp->p1;
+  assert( u.bz.iDb>=0 && u.bz.iDb<db->nDb );
+  assert( DbHasProperty(db, u.bz.iDb, DB_SchemaLoaded) );
   /* Used to be a conditional */ {
-    u.by.zMaster = SCHEMA_TABLE(u.by.iDb);
-    u.by.initData.db = db;
-    u.by.initData.iDb = pOp->p1;
-    u.by.initData.pzErrMsg = &p->zErrMsg;
-    u.by.zSql = sqlite3MPrintf(db,
+    u.bz.zMaster = SCHEMA_TABLE(u.bz.iDb);
+    u.bz.initData.db = db;
+    u.bz.initData.iDb = pOp->p1;
+    u.bz.initData.pzErrMsg = &p->zErrMsg;
+    u.bz.zSql = sqlite3MPrintf(db,
        "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
-       db->aDb[u.by.iDb].zName, u.by.zMaster, pOp->p4.z);
-    if( u.by.zSql==0 ){
+       db->aDb[u.bz.iDb].zName, u.bz.zMaster, pOp->p4.z);
+    if( u.bz.zSql==0 ){
       rc = SQLITE_NOMEM;
     }else{
       assert( db->init.busy==0 );
       db->init.busy = 1;
-      u.by.initData.rc = SQLITE_OK;
+      u.bz.initData.rc = SQLITE_OK;
       assert( !db->mallocFailed );
-      rc = sqlite3_exec(db, u.by.zSql, sqlite3InitCallback, &u.by.initData, 0);
-      if( rc==SQLITE_OK ) rc = u.by.initData.rc;
-      sqlite3DbFree(db, u.by.zSql);
+      rc = sqlite3_exec(db, u.bz.zSql, sqlite3InitCallback, &u.bz.initData, 0);
+      if( rc==SQLITE_OK ) rc = u.bz.initData.rc;
+      sqlite3DbFree(db, u.bz.zSql);
       db->init.busy = 0;
     }
   }
@@ -70775,41 +69015,41 @@ case OP_DropTrigger: {
 ** This opcode is used to implement the integrity_check pragma.
 */
 case OP_IntegrityCk: {
-#if 0  /* local variables moved into u.bz */
+#if 0  /* local variables moved into u.ca */
   int nRoot;      /* Number of tables to check.  (Number of root pages.) */
   int *aRoot;     /* Array of rootpage numbers for tables to be checked */
   int j;          /* Loop counter */
   int nErr;       /* Number of errors reported */
   char *z;        /* Text of the error report */
   Mem *pnErr;     /* Register keeping track of errors remaining */
-#endif /* local variables moved into u.bz */
+#endif /* local variables moved into u.ca */
 
-  u.bz.nRoot = pOp->p2;
-  assert( u.bz.nRoot>0 );
-  u.bz.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.bz.nRoot+1) );
-  if( u.bz.aRoot==0 ) goto no_mem;
+  u.ca.nRoot = pOp->p2;
+  assert( u.ca.nRoot>0 );
+  u.ca.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.ca.nRoot+1) );
+  if( u.ca.aRoot==0 ) goto no_mem;
   assert( pOp->p3>0 && pOp->p3<=p->nMem );
-  u.bz.pnErr = &aMem[pOp->p3];
-  assert( (u.bz.pnErr->flags & MEM_Int)!=0 );
-  assert( (u.bz.pnErr->flags & (MEM_Str|MEM_Blob))==0 );
+  u.ca.pnErr = &aMem[pOp->p3];
+  assert( (u.ca.pnErr->flags & MEM_Int)!=0 );
+  assert( (u.ca.pnErr->flags & (MEM_Str|MEM_Blob))==0 );
   pIn1 = &aMem[pOp->p1];
-  for(u.bz.j=0; u.bz.j<u.bz.nRoot; u.bz.j++){
-    u.bz.aRoot[u.bz.j] = (int)sqlite3VdbeIntValue(&pIn1[u.bz.j]);
+  for(u.ca.j=0; u.ca.j<u.ca.nRoot; u.ca.j++){
+    u.ca.aRoot[u.ca.j] = (int)sqlite3VdbeIntValue(&pIn1[u.ca.j]);
   }
-  u.bz.aRoot[u.bz.j] = 0;
+  u.ca.aRoot[u.ca.j] = 0;
   assert( pOp->p5<db->nDb );
   assert( (p->btreeMask & (((yDbMask)1)<<pOp->p5))!=0 );
-  u.bz.z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, u.bz.aRoot, u.bz.nRoot,
-                                 (int)u.bz.pnErr->u.i, &u.bz.nErr);
-  sqlite3DbFree(db, u.bz.aRoot);
-  u.bz.pnErr->u.i -= u.bz.nErr;
+  u.ca.z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, u.ca.aRoot, u.ca.nRoot,
+                                 (int)u.ca.pnErr->u.i, &u.ca.nErr);
+  sqlite3DbFree(db, u.ca.aRoot);
+  u.ca.pnErr->u.i -= u.ca.nErr;
   sqlite3VdbeMemSetNull(pIn1);
-  if( u.bz.nErr==0 ){
-    assert( u.bz.z==0 );
-  }else if( u.bz.z==0 ){
+  if( u.ca.nErr==0 ){
+    assert( u.ca.z==0 );
+  }else if( u.ca.z==0 ){
     goto no_mem;
   }else{
-    sqlite3VdbeMemSetStr(pIn1, u.bz.z, -1, SQLITE_UTF8, sqlite3_free);
+    sqlite3VdbeMemSetStr(pIn1, u.ca.z, -1, SQLITE_UTF8, sqlite3_free);
   }
   UPDATE_MAX_BLOBSIZE(pIn1);
   sqlite3VdbeChangeEncoding(pIn1, encoding);
@@ -70843,20 +69083,20 @@ case OP_RowSetAdd: {       /* in1, in2 */
 ** unchanged and jump to instruction P2.
 */
 case OP_RowSetRead: {       /* jump, in1, out3 */
-#if 0  /* local variables moved into u.ca */
+#if 0  /* local variables moved into u.cb */
   i64 val;
-#endif /* local variables moved into u.ca */
+#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.ca.val)==0
+   || sqlite3RowSetNext(pIn1->u.pRowSet, &u.cb.val)==0
   ){
     /* The boolean index is empty */
     sqlite3VdbeMemSetNull(pIn1);
     pc = pOp->p2 - 1;
   }else{
     /* A value was pulled from the index */
-    sqlite3VdbeMemSetInt64(&aMem[pOp->p3], u.ca.val);
+    sqlite3VdbeMemSetInt64(&aMem[pOp->p3], u.cb.val);
   }
   break;
 }
@@ -70885,14 +69125,14 @@ case OP_RowSetRead: {       /* jump, in1, out3 */
 ** inserted as part of some other set).
 */
 case OP_RowSetTest: {                     /* jump, in1, in3 */
-#if 0  /* local variables moved into u.cb */
+#if 0  /* local variables moved into u.cc */
   int iSet;
   int exists;
-#endif /* local variables moved into u.cb */
+#endif /* local variables moved into u.cc */
 
   pIn1 = &aMem[pOp->p1];
   pIn3 = &aMem[pOp->p3];
-  u.cb.iSet = pOp->p4.i;
+  u.cc.iSet = pOp->p4.i;
   assert( pIn3->flags&MEM_Int );
 
   /* If there is anything other than a rowset object in memory cell P1,
@@ -70904,17 +69144,17 @@ case OP_RowSetTest: {                     /* jump, in1, in3 */
   }
 
   assert( pOp->p4type==P4_INT32 );
-  assert( u.cb.iSet==-1 || u.cb.iSet>=0 );
-  if( u.cb.iSet ){
-    u.cb.exists = sqlite3RowSetTest(pIn1->u.pRowSet,
-                               (u8)(u.cb.iSet>=0 ? u.cb.iSet & 0xf : 0xff),
+  assert( u.cc.iSet==-1 || u.cc.iSet>=0 );
+  if( u.cc.iSet ){
+    u.cc.exists = sqlite3RowSetTest(pIn1->u.pRowSet,
+                               (u8)(u.cc.iSet>=0 ? u.cc.iSet & 0xf : 0xff),
                                pIn3->u.i);
-    if( u.cb.exists ){
+    if( u.cc.exists ){
       pc = pOp->p2 - 1;
       break;
     }
   }
-  if( u.cb.iSet>=0 ){
+  if( u.cc.iSet>=0 ){
     sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i);
   }
   break;
@@ -70937,7 +69177,7 @@ case OP_RowSetTest: {                     /* jump, in1, in3 */
 ** P4 is a pointer to the VM containing the trigger program.
 */
 case OP_Program: {        /* jump */
-#if 0  /* local variables moved into u.cc */
+#if 0  /* local variables moved into u.cd */
   int nMem;               /* Number of memory registers for sub-program */
   int nByte;              /* Bytes of runtime space required for sub-program */
   Mem *pRt;               /* Register to allocate runtime space */
@@ -70946,11 +69186,11 @@ case OP_Program: {        /* jump */
   VdbeFrame *pFrame;      /* New vdbe frame to execute in */
   SubProgram *pProgram;   /* Sub-program to execute */
   void *t;                /* Token identifying trigger */
-#endif /* local variables moved into u.cc */
+#endif /* local variables moved into u.cd */
 
-  u.cc.pProgram = pOp->p4.pProgram;
-  u.cc.pRt = &aMem[pOp->p3];
-  assert( u.cc.pProgram->nOp>0 );
+  u.cd.pProgram = pOp->p4.pProgram;
+  u.cd.pRt = &aMem[pOp->p3];
+  assert( u.cd.pProgram->nOp>0 );
 
   /* If the p5 flag is clear, then recursive invocation of triggers is
   ** disabled for backwards compatibility (p5 is set if this sub-program
@@ -70964,9 +69204,9 @@ case OP_Program: {        /* jump */
   ** single trigger all have the same value for the SubProgram.token
   ** variable.  */
   if( pOp->p5 ){
-    u.cc.t = u.cc.pProgram->token;
-    for(u.cc.pFrame=p->pFrame; u.cc.pFrame && u.cc.pFrame->token!=u.cc.t; u.cc.pFrame=u.cc.pFrame->pParent);
-    if( u.cc.pFrame ) break;
+    u.cd.t = u.cd.pProgram->token;
+    for(u.cd.pFrame=p->pFrame; u.cd.pFrame && u.cd.pFrame->token!=u.cd.t; u.cd.pFrame=u.cd.pFrame->pParent);
+    if( u.cd.pFrame ) break;
   }
 
   if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){
@@ -70975,69 +69215,69 @@ case OP_Program: {        /* jump */
     break;
   }
 
-  /* Register u.cc.pRt is used to store the memory required to save the state
+  /* Register u.cd.pRt is used to store the memory required to save the state
   ** of the current program, and the memory required at runtime to execute
-  ** the trigger program. If this trigger has been fired before, then u.cc.pRt
+  ** the trigger program. If this trigger has been fired before, then u.cd.pRt
   ** is already allocated. Otherwise, it must be initialized.  */
-  if( (u.cc.pRt->flags&MEM_Frame)==0 ){
+  if( (u.cd.pRt->flags&MEM_Frame)==0 ){
     /* SubProgram.nMem is set to the number of memory cells used by the
     ** program stored in SubProgram.aOp. As well as these, one memory
     ** cell is required for each cursor used by the program. Set local
-    ** variable u.cc.nMem (and later, VdbeFrame.nChildMem) to this value.
+    ** variable u.cd.nMem (and later, VdbeFrame.nChildMem) to this value.
     */
-    u.cc.nMem = u.cc.pProgram->nMem + u.cc.pProgram->nCsr;
-    u.cc.nByte = ROUND8(sizeof(VdbeFrame))
-              + u.cc.nMem * sizeof(Mem)
-              + u.cc.pProgram->nCsr * sizeof(VdbeCursor *)
-              + u.cc.pProgram->nOnce * sizeof(u8);
-    u.cc.pFrame = sqlite3DbMallocZero(db, u.cc.nByte);
-    if( !u.cc.pFrame ){
+    u.cd.nMem = u.cd.pProgram->nMem + u.cd.pProgram->nCsr;
+    u.cd.nByte = ROUND8(sizeof(VdbeFrame))
+              + u.cd.nMem * sizeof(Mem)
+              + u.cd.pProgram->nCsr * sizeof(VdbeCursor *)
+              + u.cd.pProgram->nOnce * sizeof(u8);
+    u.cd.pFrame = sqlite3DbMallocZero(db, u.cd.nByte);
+    if( !u.cd.pFrame ){
       goto no_mem;
     }
-    sqlite3VdbeMemRelease(u.cc.pRt);
-    u.cc.pRt->flags = MEM_Frame;
-    u.cc.pRt->u.pFrame = u.cc.pFrame;
+    sqlite3VdbeMemRelease(u.cd.pRt);
+    u.cd.pRt->flags = MEM_Frame;
+    u.cd.pRt->u.pFrame = u.cd.pFrame;
 
-    u.cc.pFrame->v = p;
-    u.cc.pFrame->nChildMem = u.cc.nMem;
-    u.cc.pFrame->nChildCsr = u.cc.pProgram->nCsr;
-    u.cc.pFrame->pc = pc;
-    u.cc.pFrame->aMem = p->aMem;
-    u.cc.pFrame->nMem = p->nMem;
-    u.cc.pFrame->apCsr = p->apCsr;
-    u.cc.pFrame->nCursor = p->nCursor;
-    u.cc.pFrame->aOp = p->aOp;
-    u.cc.pFrame->nOp = p->nOp;
-    u.cc.pFrame->token = u.cc.pProgram->token;
-    u.cc.pFrame->aOnceFlag = p->aOnceFlag;
-    u.cc.pFrame->nOnceFlag = p->nOnceFlag;
+    u.cd.pFrame->v = p;
+    u.cd.pFrame->nChildMem = u.cd.nMem;
+    u.cd.pFrame->nChildCsr = u.cd.pProgram->nCsr;
+    u.cd.pFrame->pc = pc;
+    u.cd.pFrame->aMem = p->aMem;
+    u.cd.pFrame->nMem = p->nMem;
+    u.cd.pFrame->apCsr = p->apCsr;
+    u.cd.pFrame->nCursor = p->nCursor;
+    u.cd.pFrame->aOp = p->aOp;
+    u.cd.pFrame->nOp = p->nOp;
+    u.cd.pFrame->token = u.cd.pProgram->token;
+    u.cd.pFrame->aOnceFlag = p->aOnceFlag;
+    u.cd.pFrame->nOnceFlag = p->nOnceFlag;
 
-    u.cc.pEnd = &VdbeFrameMem(u.cc.pFrame)[u.cc.pFrame->nChildMem];
-    for(u.cc.pMem=VdbeFrameMem(u.cc.pFrame); u.cc.pMem!=u.cc.pEnd; u.cc.pMem++){
-      u.cc.pMem->flags = MEM_Invalid;
-      u.cc.pMem->db = db;
+    u.cd.pEnd = &VdbeFrameMem(u.cd.pFrame)[u.cd.pFrame->nChildMem];
+    for(u.cd.pMem=VdbeFrameMem(u.cd.pFrame); u.cd.pMem!=u.cd.pEnd; u.cd.pMem++){
+      u.cd.pMem->flags = MEM_Invalid;
+      u.cd.pMem->db = db;
     }
   }else{
-    u.cc.pFrame = u.cc.pRt->u.pFrame;
-    assert( u.cc.pProgram->nMem+u.cc.pProgram->nCsr==u.cc.pFrame->nChildMem );
-    assert( u.cc.pProgram->nCsr==u.cc.pFrame->nChildCsr );
-    assert( pc==u.cc.pFrame->pc );
+    u.cd.pFrame = u.cd.pRt->u.pFrame;
+    assert( u.cd.pProgram->nMem+u.cd.pProgram->nCsr==u.cd.pFrame->nChildMem );
+    assert( u.cd.pProgram->nCsr==u.cd.pFrame->nChildCsr );
+    assert( pc==u.cd.pFrame->pc );
   }
 
   p->nFrame++;
-  u.cc.pFrame->pParent = p->pFrame;
-  u.cc.pFrame->lastRowid = lastRowid;
-  u.cc.pFrame->nChange = p->nChange;
+  u.cd.pFrame->pParent = p->pFrame;
+  u.cd.pFrame->lastRowid = lastRowid;
+  u.cd.pFrame->nChange = p->nChange;
   p->nChange = 0;
-  p->pFrame = u.cc.pFrame;
-  p->aMem = aMem = &VdbeFrameMem(u.cc.pFrame)[-1];
-  p->nMem = u.cc.pFrame->nChildMem;
-  p->nCursor = (u16)u.cc.pFrame->nChildCsr;
+  p->pFrame = u.cd.pFrame;
+  p->aMem = aMem = &VdbeFrameMem(u.cd.pFrame)[-1];
+  p->nMem = u.cd.pFrame->nChildMem;
+  p->nCursor = (u16)u.cd.pFrame->nChildCsr;
   p->apCsr = (VdbeCursor **)&aMem[p->nMem+1];
-  p->aOp = aOp = u.cc.pProgram->aOp;
-  p->nOp = u.cc.pProgram->nOp;
+  p->aOp = aOp = u.cd.pProgram->aOp;
+  p->nOp = u.cd.pProgram->nOp;
   p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor];
-  p->nOnceFlag = u.cc.pProgram->nOnce;
+  p->nOnceFlag = u.cd.pProgram->nOnce;
   pc = -1;
   memset(p->aOnceFlag, 0, p->nOnceFlag);
 
@@ -71057,13 +69297,13 @@ case OP_Program: {        /* jump */
 ** calling OP_Program instruction.
 */
 case OP_Param: {           /* out2-prerelease */
-#if 0  /* local variables moved into u.cd */
+#if 0  /* local variables moved into u.ce */
   VdbeFrame *pFrame;
   Mem *pIn;
-#endif /* local variables moved into u.cd */
-  u.cd.pFrame = p->pFrame;
-  u.cd.pIn = &u.cd.pFrame->aMem[pOp->p1 + u.cd.pFrame->aOp[u.cd.pFrame->pc].p1];
-  sqlite3VdbeMemShallowCopy(pOut, u.cd.pIn, MEM_Ephem);
+#endif /* local variables moved into u.ce */
+  u.ce.pFrame = p->pFrame;
+  u.ce.pIn = &u.ce.pFrame->aMem[pOp->p1 + u.ce.pFrame->aOp[u.ce.pFrame->pc].p1];
+  sqlite3VdbeMemShallowCopy(pOut, u.ce.pIn, MEM_Ephem);
   break;
 }
 
@@ -71119,22 +69359,22 @@ case OP_FkIfZero: {         /* jump */
 ** an integer.
 */
 case OP_MemMax: {        /* in2 */
-#if 0  /* local variables moved into u.ce */
+#if 0  /* local variables moved into u.cf */
   Mem *pIn1;
   VdbeFrame *pFrame;
-#endif /* local variables moved into u.ce */
+#endif /* local variables moved into u.cf */
   if( p->pFrame ){
-    for(u.ce.pFrame=p->pFrame; u.ce.pFrame->pParent; u.ce.pFrame=u.ce.pFrame->pParent);
-    u.ce.pIn1 = &u.ce.pFrame->aMem[pOp->p1];
+    for(u.cf.pFrame=p->pFrame; u.cf.pFrame->pParent; u.cf.pFrame=u.cf.pFrame->pParent);
+    u.cf.pIn1 = &u.cf.pFrame->aMem[pOp->p1];
   }else{
-    u.ce.pIn1 = &aMem[pOp->p1];
+    u.cf.pIn1 = &aMem[pOp->p1];
   }
-  assert( memIsValid(u.ce.pIn1) );
-  sqlite3VdbeMemIntegerify(u.ce.pIn1);
+  assert( memIsValid(u.cf.pIn1) );
+  sqlite3VdbeMemIntegerify(u.cf.pIn1);
   pIn2 = &aMem[pOp->p2];
   sqlite3VdbeMemIntegerify(pIn2);
-  if( u.ce.pIn1->u.i<pIn2->u.i){
-    u.ce.pIn1->u.i = pIn2->u.i;
+  if( u.cf.pIn1->u.i<pIn2->u.i){
+    u.cf.pIn1->u.i = pIn2->u.i;
   }
   break;
 }
@@ -71201,56 +69441,56 @@ case OP_IfZero: {        /* jump, in1 */
 ** successors.
 */
 case OP_AggStep: {
-#if 0  /* local variables moved into u.cf */
+#if 0  /* local variables moved into u.cg */
   int n;
   int i;
   Mem *pMem;
   Mem *pRec;
   sqlite3_context ctx;
   sqlite3_value **apVal;
-#endif /* local variables moved into u.cf */
+#endif /* local variables moved into u.cg */
 
-  u.cf.n = pOp->p5;
-  assert( u.cf.n>=0 );
-  u.cf.pRec = &aMem[pOp->p2];
-  u.cf.apVal = p->apArg;
-  assert( u.cf.apVal || u.cf.n==0 );
-  for(u.cf.i=0; u.cf.i<u.cf.n; u.cf.i++, u.cf.pRec++){
-    assert( memIsValid(u.cf.pRec) );
-    u.cf.apVal[u.cf.i] = u.cf.pRec;
-    memAboutToChange(p, u.cf.pRec);
-    sqlite3VdbeMemStoreType(u.cf.pRec);
-  }
-  u.cf.ctx.pFunc = pOp->p4.pFunc;
+  u.cg.n = pOp->p5;
+  assert( u.cg.n>=0 );
+  u.cg.pRec = &aMem[pOp->p2];
+  u.cg.apVal = p->apArg;
+  assert( u.cg.apVal || u.cg.n==0 );
+  for(u.cg.i=0; u.cg.i<u.cg.n; u.cg.i++, u.cg.pRec++){
+    assert( memIsValid(u.cg.pRec) );
+    u.cg.apVal[u.cg.i] = u.cg.pRec;
+    memAboutToChange(p, u.cg.pRec);
+    sqlite3VdbeMemStoreType(u.cg.pRec);
+  }
+  u.cg.ctx.pFunc = pOp->p4.pFunc;
   assert( pOp->p3>0 && pOp->p3<=p->nMem );
-  u.cf.ctx.pMem = u.cf.pMem = &aMem[pOp->p3];
-  u.cf.pMem->n++;
-  u.cf.ctx.s.flags = MEM_Null;
-  u.cf.ctx.s.z = 0;
-  u.cf.ctx.s.zMalloc = 0;
-  u.cf.ctx.s.xDel = 0;
-  u.cf.ctx.s.db = db;
-  u.cf.ctx.isError = 0;
-  u.cf.ctx.pColl = 0;
-  u.cf.ctx.skipFlag = 0;
-  if( u.cf.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
+  u.cg.ctx.pMem = u.cg.pMem = &aMem[pOp->p3];
+  u.cg.pMem->n++;
+  u.cg.ctx.s.flags = MEM_Null;
+  u.cg.ctx.s.z = 0;
+  u.cg.ctx.s.zMalloc = 0;
+  u.cg.ctx.s.xDel = 0;
+  u.cg.ctx.s.db = db;
+  u.cg.ctx.isError = 0;
+  u.cg.ctx.pColl = 0;
+  u.cg.ctx.skipFlag = 0;
+  if( u.cg.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
     assert( pOp>p->aOp );
     assert( pOp[-1].p4type==P4_COLLSEQ );
     assert( pOp[-1].opcode==OP_CollSeq );
-    u.cf.ctx.pColl = pOp[-1].p4.pColl;
+    u.cg.ctx.pColl = pOp[-1].p4.pColl;
   }
-  (u.cf.ctx.pFunc->xStep)(&u.cf.ctx, u.cf.n, u.cf.apVal); /* IMP: R-24505-23230 */
-  if( u.cf.ctx.isError ){
-    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.cf.ctx.s));
-    rc = u.cf.ctx.isError;
+  (u.cg.ctx.pFunc->xStep)(&u.cg.ctx, u.cg.n, u.cg.apVal); /* IMP: R-24505-23230 */
+  if( u.cg.ctx.isError ){
+    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.cg.ctx.s));
+    rc = u.cg.ctx.isError;
   }
-  if( u.cf.ctx.skipFlag ){
+  if( u.cg.ctx.skipFlag ){
     assert( pOp[-1].opcode==OP_CollSeq );
-    u.cf.i = pOp[-1].p1;
-    if( u.cf.i ) sqlite3VdbeMemSetInt64(&aMem[u.cf.i], 1);
+    u.cg.i = pOp[-1].p1;
+    if( u.cg.i ) sqlite3VdbeMemSetInt64(&aMem[u.cg.i], 1);
   }
 
-  sqlite3VdbeMemRelease(&u.cf.ctx.s);
+  sqlite3VdbeMemRelease(&u.cg.ctx.s);
 
   break;
 }
@@ -71268,19 +69508,19 @@ case OP_AggStep: {
 ** the step function was not previously called.
 */
 case OP_AggFinal: {
-#if 0  /* local variables moved into u.cg */
+#if 0  /* local variables moved into u.ch */
   Mem *pMem;
-#endif /* local variables moved into u.cg */
+#endif /* local variables moved into u.ch */
   assert( pOp->p1>0 && pOp->p1<=p->nMem );
-  u.cg.pMem = &aMem[pOp->p1];
-  assert( (u.cg.pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
-  rc = sqlite3VdbeMemFinalize(u.cg.pMem, pOp->p4.pFunc);
+  u.ch.pMem = &aMem[pOp->p1];
+  assert( (u.ch.pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
+  rc = sqlite3VdbeMemFinalize(u.ch.pMem, pOp->p4.pFunc);
   if( rc ){
-    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.cg.pMem));
+    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.ch.pMem));
   }
-  sqlite3VdbeChangeEncoding(u.cg.pMem, encoding);
-  UPDATE_MAX_BLOBSIZE(u.cg.pMem);
-  if( sqlite3VdbeMemTooBig(u.cg.pMem) ){
+  sqlite3VdbeChangeEncoding(u.ch.pMem, encoding);
+  UPDATE_MAX_BLOBSIZE(u.ch.pMem);
+  if( sqlite3VdbeMemTooBig(u.ch.pMem) ){
     goto too_big;
   }
   break;
@@ -71299,25 +69539,25 @@ case OP_AggFinal: {
 ** mem[P3+2] are initialized to -1.
 */
 case OP_Checkpoint: {
-#if 0  /* local variables moved into u.ch */
+#if 0  /* local variables moved into u.ci */
   int i;                          /* Loop counter */
   int aRes[3];                    /* Results */
   Mem *pMem;                      /* Write results here */
-#endif /* local variables moved into u.ch */
+#endif /* local variables moved into u.ci */
 
-  u.ch.aRes[0] = 0;
-  u.ch.aRes[1] = u.ch.aRes[2] = -1;
+  u.ci.aRes[0] = 0;
+  u.ci.aRes[1] = u.ci.aRes[2] = -1;
   assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE
        || pOp->p2==SQLITE_CHECKPOINT_FULL
        || pOp->p2==SQLITE_CHECKPOINT_RESTART
   );
-  rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &u.ch.aRes[1], &u.ch.aRes[2]);
+  rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &u.ci.aRes[1], &u.ci.aRes[2]);
   if( rc==SQLITE_BUSY ){
     rc = SQLITE_OK;
-    u.ch.aRes[0] = 1;
+    u.ci.aRes[0] = 1;
   }
-  for(u.ch.i=0, u.ch.pMem = &aMem[pOp->p3]; u.ch.i<3; u.ch.i++, u.ch.pMem++){
-    sqlite3VdbeMemSetInt64(u.ch.pMem, (i64)u.ch.aRes[u.ch.i]);
+  for(u.ci.i=0, u.ci.pMem = &aMem[pOp->p3]; u.ci.i<3; u.ci.i++, u.ci.pMem++){
+    sqlite3VdbeMemSetInt64(u.ci.pMem, (i64)u.ci.aRes[u.ci.i]);
   }
   break;
 };  
@@ -71336,91 +69576,93 @@ case OP_Checkpoint: {
 ** Write a string containing the final journal-mode to register P2.
 */
 case OP_JournalMode: {    /* out2-prerelease */
-#if 0  /* local variables moved into u.ci */
+#if 0  /* local variables moved into u.cj */
   Btree *pBt;                     /* Btree to change journal mode of */
   Pager *pPager;                  /* Pager associated with pBt */
   int eNew;                       /* New journal mode */
   int eOld;                       /* The old journal mode */
+#ifndef SQLITE_OMIT_WAL
   const char *zFilename;          /* Name of database file for pPager */
-#endif /* local variables moved into u.ci */
+#endif
+#endif /* local variables moved into u.cj */
 
-  u.ci.eNew = pOp->p3;
-  assert( u.ci.eNew==PAGER_JOURNALMODE_DELETE
-       || u.ci.eNew==PAGER_JOURNALMODE_TRUNCATE
-       || u.ci.eNew==PAGER_JOURNALMODE_PERSIST
-       || u.ci.eNew==PAGER_JOURNALMODE_OFF
-       || u.ci.eNew==PAGER_JOURNALMODE_MEMORY
-       || u.ci.eNew==PAGER_JOURNALMODE_WAL
-       || u.ci.eNew==PAGER_JOURNALMODE_QUERY
+  u.cj.eNew = pOp->p3;
+  assert( u.cj.eNew==PAGER_JOURNALMODE_DELETE
+       || u.cj.eNew==PAGER_JOURNALMODE_TRUNCATE
+       || u.cj.eNew==PAGER_JOURNALMODE_PERSIST
+       || u.cj.eNew==PAGER_JOURNALMODE_OFF
+       || u.cj.eNew==PAGER_JOURNALMODE_MEMORY
+       || u.cj.eNew==PAGER_JOURNALMODE_WAL
+       || u.cj.eNew==PAGER_JOURNALMODE_QUERY
   );
   assert( pOp->p1>=0 && pOp->p1<db->nDb );
 
-  u.ci.pBt = db->aDb[pOp->p1].pBt;
-  u.ci.pPager = sqlite3BtreePager(u.ci.pBt);
-  u.ci.eOld = sqlite3PagerGetJournalMode(u.ci.pPager);
-  if( u.ci.eNew==PAGER_JOURNALMODE_QUERY ) u.ci.eNew = u.ci.eOld;
-  if( !sqlite3PagerOkToChangeJournalMode(u.ci.pPager) ) u.ci.eNew = u.ci.eOld;
+  u.cj.pBt = db->aDb[pOp->p1].pBt;
+  u.cj.pPager = sqlite3BtreePager(u.cj.pBt);
+  u.cj.eOld = sqlite3PagerGetJournalMode(u.cj.pPager);
+  if( u.cj.eNew==PAGER_JOURNALMODE_QUERY ) u.cj.eNew = u.cj.eOld;
+  if( !sqlite3PagerOkToChangeJournalMode(u.cj.pPager) ) u.cj.eNew = u.cj.eOld;
 
 #ifndef SQLITE_OMIT_WAL
-  u.ci.zFilename = sqlite3PagerFilename(u.ci.pPager, 1);
+  u.cj.zFilename = sqlite3PagerFilename(u.cj.pPager, 1);
 
   /* Do not allow a transition to journal_mode=WAL for a database
   ** in temporary storage or if the VFS does not support shared memory
   */
-  if( u.ci.eNew==PAGER_JOURNALMODE_WAL
-   && (sqlite3Strlen30(u.ci.zFilename)==0           /* Temp file */
-       || !sqlite3PagerWalSupported(u.ci.pPager))   /* No shared-memory support */
+  if( u.cj.eNew==PAGER_JOURNALMODE_WAL
+   && (sqlite3Strlen30(u.cj.zFilename)==0           /* Temp file */
+       || !sqlite3PagerWalSupported(u.cj.pPager))   /* No shared-memory support */
   ){
-    u.ci.eNew = u.ci.eOld;
+    u.cj.eNew = u.cj.eOld;
   }
 
-  if( (u.ci.eNew!=u.ci.eOld)
-   && (u.ci.eOld==PAGER_JOURNALMODE_WAL || u.ci.eNew==PAGER_JOURNALMODE_WAL)
+  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 ){
       rc = SQLITE_ERROR;
       sqlite3SetString(&p->zErrMsg, db,
           "cannot change %s wal mode from within a transaction",
-          (u.ci.eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of")
+          (u.cj.eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of")
       );
       break;
     }else{
 
-      if( u.ci.eOld==PAGER_JOURNALMODE_WAL ){
+      if( u.cj.eOld==PAGER_JOURNALMODE_WAL ){
         /* If leaving WAL mode, close the log file. If successful, the call
         ** to PagerCloseWal() checkpoints and deletes the write-ahead-log
         ** file. An EXCLUSIVE lock may still be held on the database file
         ** after a successful return.
         */
-        rc = sqlite3PagerCloseWal(u.ci.pPager);
+        rc = sqlite3PagerCloseWal(u.cj.pPager);
         if( rc==SQLITE_OK ){
-          sqlite3PagerSetJournalMode(u.ci.pPager, u.ci.eNew);
+          sqlite3PagerSetJournalMode(u.cj.pPager, u.cj.eNew);
         }
-      }else if( u.ci.eOld==PAGER_JOURNALMODE_MEMORY ){
+      }else if( u.cj.eOld==PAGER_JOURNALMODE_MEMORY ){
         /* Cannot transition directly from MEMORY to WAL.  Use mode OFF
         ** as an intermediate */
-        sqlite3PagerSetJournalMode(u.ci.pPager, PAGER_JOURNALMODE_OFF);
+        sqlite3PagerSetJournalMode(u.cj.pPager, PAGER_JOURNALMODE_OFF);
       }
 
       /* Open a transaction on the database file. Regardless of the journal
       ** mode, this transaction always uses a rollback journal.
       */
-      assert( sqlite3BtreeIsInTrans(u.ci.pBt)==0 );
+      assert( sqlite3BtreeIsInTrans(u.cj.pBt)==0 );
       if( rc==SQLITE_OK ){
-        rc = sqlite3BtreeSetVersion(u.ci.pBt, (u.ci.eNew==PAGER_JOURNALMODE_WAL ? 2 : 1));
+        rc = sqlite3BtreeSetVersion(u.cj.pBt, (u.cj.eNew==PAGER_JOURNALMODE_WAL ? 2 : 1));
       }
     }
   }
 #endif /* ifndef SQLITE_OMIT_WAL */
 
   if( rc ){
-    u.ci.eNew = u.ci.eOld;
+    u.cj.eNew = u.cj.eOld;
   }
-  u.ci.eNew = sqlite3PagerSetJournalMode(u.ci.pPager, u.ci.eNew);
+  u.cj.eNew = sqlite3PagerSetJournalMode(u.cj.pPager, u.cj.eNew);
 
   pOut = &aMem[pOp->p2];
   pOut->flags = MEM_Str|MEM_Static|MEM_Term;
-  pOut->z = (char *)sqlite3JournalModename(u.ci.eNew);
+  pOut->z = (char *)sqlite3JournalModename(u.cj.eNew);
   pOut->n = sqlite3Strlen30(pOut->z);
   pOut->enc = SQLITE_UTF8;
   sqlite3VdbeChangeEncoding(pOut, encoding);
@@ -71449,14 +69691,14 @@ case OP_Vacuum: {
 ** P2. Otherwise, fall through to the next instruction.
 */
 case OP_IncrVacuum: {        /* jump */
-#if 0  /* local variables moved into u.cj */
+#if 0  /* local variables moved into u.ck */
   Btree *pBt;
-#endif /* local variables moved into u.cj */
+#endif /* local variables moved into u.ck */
 
   assert( pOp->p1>=0 && pOp->p1<db->nDb );
   assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
-  u.cj.pBt = db->aDb[pOp->p1].pBt;
-  rc = sqlite3BtreeIncrVacuum(u.cj.pBt);
+  u.ck.pBt = db->aDb[pOp->p1].pBt;
+  rc = sqlite3BtreeIncrVacuum(u.ck.pBt);
   if( rc==SQLITE_DONE ){
     pc = pOp->p2 - 1;
     rc = SQLITE_OK;
@@ -71526,12 +69768,12 @@ case OP_TableLock: {
 ** code will be set to SQLITE_LOCKED.
 */
 case OP_VBegin: {
-#if 0  /* local variables moved into u.ck */
+#if 0  /* local variables moved into u.cl */
   VTable *pVTab;
-#endif /* local variables moved into u.ck */
-  u.ck.pVTab = pOp->p4.pVtab;
-  rc = sqlite3VtabBegin(db, u.ck.pVTab);
-  if( u.ck.pVTab ) importVtabErrMsg(p, u.ck.pVTab->pVtab);
+#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);
   break;
 }
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -71570,32 +69812,32 @@ case OP_VDestroy: {
 ** table and stores that cursor in P1.
 */
 case OP_VOpen: {
-#if 0  /* local variables moved into u.cl */
+#if 0  /* local variables moved into u.cm */
   VdbeCursor *pCur;
   sqlite3_vtab_cursor *pVtabCursor;
   sqlite3_vtab *pVtab;
   sqlite3_module *pModule;
-#endif /* local variables moved into u.cl */
+#endif /* local variables moved into u.cm */
 
-  u.cl.pCur = 0;
-  u.cl.pVtabCursor = 0;
-  u.cl.pVtab = pOp->p4.pVtab->pVtab;
-  u.cl.pModule = (sqlite3_module *)u.cl.pVtab->pModule;
-  assert(u.cl.pVtab && u.cl.pModule);
-  rc = u.cl.pModule->xOpen(u.cl.pVtab, &u.cl.pVtabCursor);
-  importVtabErrMsg(p, u.cl.pVtab);
+  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);
   if( SQLITE_OK==rc ){
     /* Initialize sqlite3_vtab_cursor base class */
-    u.cl.pVtabCursor->pVtab = u.cl.pVtab;
+    u.cm.pVtabCursor->pVtab = u.cm.pVtab;
 
     /* Initialise vdbe cursor object */
-    u.cl.pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
-    if( u.cl.pCur ){
-      u.cl.pCur->pVtabCursor = u.cl.pVtabCursor;
-      u.cl.pCur->pModule = u.cl.pVtabCursor->pVtab->pModule;
+    u.cm.pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
+    if( u.cm.pCur ){
+      u.cm.pCur->pVtabCursor = u.cm.pVtabCursor;
+      u.cm.pCur->pModule = u.cm.pVtabCursor->pVtab->pModule;
     }else{
       db->mallocFailed = 1;
-      u.cl.pModule->xClose(u.cl.pVtabCursor);
+      u.cm.pModule->xClose(u.cm.pVtabCursor);
     }
   }
   break;
@@ -71622,7 +69864,7 @@ case OP_VOpen: {
 ** A jump is made to P2 if the result set after filtering would be empty.
 */
 case OP_VFilter: {   /* jump */
-#if 0  /* local variables moved into u.cm */
+#if 0  /* local variables moved into u.cn */
   int nArg;
   int iQuery;
   const sqlite3_module *pModule;
@@ -71634,45 +69876,45 @@ case OP_VFilter: {   /* jump */
   int res;
   int i;
   Mem **apArg;
-#endif /* local variables moved into u.cm */
+#endif /* local variables moved into u.cn */
 
-  u.cm.pQuery = &aMem[pOp->p3];
-  u.cm.pArgc = &u.cm.pQuery[1];
-  u.cm.pCur = p->apCsr[pOp->p1];
-  assert( memIsValid(u.cm.pQuery) );
-  REGISTER_TRACE(pOp->p3, u.cm.pQuery);
-  assert( u.cm.pCur->pVtabCursor );
-  u.cm.pVtabCursor = u.cm.pCur->pVtabCursor;
-  u.cm.pVtab = u.cm.pVtabCursor->pVtab;
-  u.cm.pModule = u.cm.pVtab->pModule;
+  u.cn.pQuery = &aMem[pOp->p3];
+  u.cn.pArgc = &u.cn.pQuery[1];
+  u.cn.pCur = p->apCsr[pOp->p1];
+  assert( memIsValid(u.cn.pQuery) );
+  REGISTER_TRACE(pOp->p3, u.cn.pQuery);
+  assert( u.cn.pCur->pVtabCursor );
+  u.cn.pVtabCursor = u.cn.pCur->pVtabCursor;
+  u.cn.pVtab = u.cn.pVtabCursor->pVtab;
+  u.cn.pModule = u.cn.pVtab->pModule;
 
   /* Grab the index number and argc parameters */
-  assert( (u.cm.pQuery->flags&MEM_Int)!=0 && u.cm.pArgc->flags==MEM_Int );
-  u.cm.nArg = (int)u.cm.pArgc->u.i;
-  u.cm.iQuery = (int)u.cm.pQuery->u.i;
+  assert( (u.cn.pQuery->flags&MEM_Int)!=0 && u.cn.pArgc->flags==MEM_Int );
+  u.cn.nArg = (int)u.cn.pArgc->u.i;
+  u.cn.iQuery = (int)u.cn.pQuery->u.i;
 
   /* Invoke the xFilter method */
   {
-    u.cm.res = 0;
-    u.cm.apArg = p->apArg;
-    for(u.cm.i = 0; u.cm.i<u.cm.nArg; u.cm.i++){
-      u.cm.apArg[u.cm.i] = &u.cm.pArgc[u.cm.i+1];
-      sqlite3VdbeMemStoreType(u.cm.apArg[u.cm.i]);
+    u.cn.res = 0;
+    u.cn.apArg = p->apArg;
+    for(u.cn.i = 0; u.cn.i<u.cn.nArg; u.cn.i++){
+      u.cn.apArg[u.cn.i] = &u.cn.pArgc[u.cn.i+1];
+      sqlite3VdbeMemStoreType(u.cn.apArg[u.cn.i]);
     }
 
     p->inVtabMethod = 1;
-    rc = u.cm.pModule->xFilter(u.cm.pVtabCursor, u.cm.iQuery, pOp->p4.z, u.cm.nArg, u.cm.apArg);
+    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.cm.pVtab);
+    importVtabErrMsg(p, u.cn.pVtab);
     if( rc==SQLITE_OK ){
-      u.cm.res = u.cm.pModule->xEof(u.cm.pVtabCursor);
+      u.cn.res = u.cn.pModule->xEof(u.cn.pVtabCursor);
     }
 
-    if( u.cm.res ){
+    if( u.cn.res ){
       pc = pOp->p2 - 1;
     }
   }
-  u.cm.pCur->nullRow = 0;
+  u.cn.pCur->nullRow = 0;
 
   break;
 }
@@ -71686,51 +69928,51 @@ case OP_VFilter: {   /* jump */
 ** P1 cursor is pointing to into register P3.
 */
 case OP_VColumn: {
-#if 0  /* local variables moved into u.cn */
+#if 0  /* local variables moved into u.co */
   sqlite3_vtab *pVtab;
   const sqlite3_module *pModule;
   Mem *pDest;
   sqlite3_context sContext;
-#endif /* local variables moved into u.cn */
+#endif /* local variables moved into u.co */
 
   VdbeCursor *pCur = p->apCsr[pOp->p1];
   assert( pCur->pVtabCursor );
   assert( pOp->p3>0 && pOp->p3<=p->nMem );
-  u.cn.pDest = &aMem[pOp->p3];
-  memAboutToChange(p, u.cn.pDest);
+  u.co.pDest = &aMem[pOp->p3];
+  memAboutToChange(p, u.co.pDest);
   if( pCur->nullRow ){
-    sqlite3VdbeMemSetNull(u.cn.pDest);
+    sqlite3VdbeMemSetNull(u.co.pDest);
     break;
   }
-  u.cn.pVtab = pCur->pVtabCursor->pVtab;
-  u.cn.pModule = u.cn.pVtab->pModule;
-  assert( u.cn.pModule->xColumn );
-  memset(&u.cn.sContext, 0, sizeof(u.cn.sContext));
+  u.co.pVtab = pCur->pVtabCursor->pVtab;
+  u.co.pModule = u.co.pVtab->pModule;
+  assert( u.co.pModule->xColumn );
+  memset(&u.co.sContext, 0, sizeof(u.co.sContext));
 
   /* The output cell may already have a buffer allocated. Move
-  ** the current contents to u.cn.sContext.s so in case the user-function
+  ** the current contents to u.co.sContext.s so in case the user-function
   ** can use the already allocated buffer instead of allocating a
   ** new one.
   */
-  sqlite3VdbeMemMove(&u.cn.sContext.s, u.cn.pDest);
-  MemSetTypeFlag(&u.cn.sContext.s, MEM_Null);
+  sqlite3VdbeMemMove(&u.co.sContext.s, u.co.pDest);
+  MemSetTypeFlag(&u.co.sContext.s, MEM_Null);
 
-  rc = u.cn.pModule->xColumn(pCur->pVtabCursor, &u.cn.sContext, pOp->p2);
-  importVtabErrMsg(p, u.cn.pVtab);
-  if( u.cn.sContext.isError ){
-    rc = u.cn.sContext.isError;
+  rc = u.co.pModule->xColumn(pCur->pVtabCursor, &u.co.sContext, pOp->p2);
+  importVtabErrMsg(p, u.co.pVtab);
+  if( u.co.sContext.isError ){
+    rc = u.co.sContext.isError;
   }
 
   /* Copy the result of the function to the P3 register. We
   ** do this regardless of whether or not an error occurred to ensure any
-  ** dynamic allocation in u.cn.sContext.s (a Mem struct) is  released.
+  ** dynamic allocation in u.co.sContext.s (a Mem struct) is  released.
   */
-  sqlite3VdbeChangeEncoding(&u.cn.sContext.s, encoding);
-  sqlite3VdbeMemMove(u.cn.pDest, &u.cn.sContext.s);
-  REGISTER_TRACE(pOp->p3, u.cn.pDest);
-  UPDATE_MAX_BLOBSIZE(u.cn.pDest);
+  sqlite3VdbeChangeEncoding(&u.co.sContext.s, encoding);
+  sqlite3VdbeMemMove(u.co.pDest, &u.co.sContext.s);
+  REGISTER_TRACE(pOp->p3, u.co.pDest);
+  UPDATE_MAX_BLOBSIZE(u.co.pDest);
 
-  if( sqlite3VdbeMemTooBig(u.cn.pDest) ){
+  if( sqlite3VdbeMemTooBig(u.co.pDest) ){
     goto too_big;
   }
   break;
@@ -71745,22 +69987,22 @@ case OP_VColumn: {
 ** the end of its result set, then fall through to the next instruction.
 */
 case OP_VNext: {   /* jump */
-#if 0  /* local variables moved into u.co */
+#if 0  /* local variables moved into u.cp */
   sqlite3_vtab *pVtab;
   const sqlite3_module *pModule;
   int res;
   VdbeCursor *pCur;
-#endif /* local variables moved into u.co */
+#endif /* local variables moved into u.cp */
 
-  u.co.res = 0;
-  u.co.pCur = p->apCsr[pOp->p1];
-  assert( u.co.pCur->pVtabCursor );
-  if( u.co.pCur->nullRow ){
+  u.cp.res = 0;
+  u.cp.pCur = p->apCsr[pOp->p1];
+  assert( u.cp.pCur->pVtabCursor );
+  if( u.cp.pCur->nullRow ){
     break;
   }
-  u.co.pVtab = u.co.pCur->pVtabCursor->pVtab;
-  u.co.pModule = u.co.pVtab->pModule;
-  assert( u.co.pModule->xNext );
+  u.cp.pVtab = u.cp.pCur->pVtabCursor->pVtab;
+  u.cp.pModule = u.cp.pVtab->pModule;
+  assert( u.cp.pModule->xNext );
 
   /* Invoke the xNext() method of the module. There is no way for the
   ** underlying implementation to return an error if one occurs during
@@ -71769,14 +70011,14 @@ case OP_VNext: {   /* jump */
   ** some other method is next invoked on the save virtual table cursor.
   */
   p->inVtabMethod = 1;
-  rc = u.co.pModule->xNext(u.co.pCur->pVtabCursor);
+  rc = u.cp.pModule->xNext(u.cp.pCur->pVtabCursor);
   p->inVtabMethod = 0;
-  importVtabErrMsg(p, u.co.pVtab);
+  importVtabErrMsg(p, u.cp.pVtab);
   if( rc==SQLITE_OK ){
-    u.co.res = u.co.pModule->xEof(u.co.pCur->pVtabCursor);
+    u.cp.res = u.cp.pModule->xEof(u.cp.pCur->pVtabCursor);
   }
 
-  if( !u.co.res ){
+  if( !u.cp.res ){
     /* If there is data, jump to P2 */
     pc = pOp->p2 - 1;
   }
@@ -71792,24 +70034,24 @@ case OP_VNext: {   /* jump */
 ** in register P1 is passed as the zName argument to the xRename method.
 */
 case OP_VRename: {
-#if 0  /* local variables moved into u.cp */
+#if 0  /* local variables moved into u.cq */
   sqlite3_vtab *pVtab;
   Mem *pName;
-#endif /* local variables moved into u.cp */
+#endif /* local variables moved into u.cq */
 
-  u.cp.pVtab = pOp->p4.pVtab->pVtab;
-  u.cp.pName = &aMem[pOp->p1];
-  assert( u.cp.pVtab->pModule->xRename );
-  assert( memIsValid(u.cp.pName) );
-  REGISTER_TRACE(pOp->p1, u.cp.pName);
-  assert( u.cp.pName->flags & MEM_Str );
-  testcase( u.cp.pName->enc==SQLITE_UTF8 );
-  testcase( u.cp.pName->enc==SQLITE_UTF16BE );
-  testcase( u.cp.pName->enc==SQLITE_UTF16LE );
-  rc = sqlite3VdbeChangeEncoding(u.cp.pName, SQLITE_UTF8);
+  u.cq.pVtab = pOp->p4.pVtab->pVtab;
+  u.cq.pName = &aMem[pOp->p1];
+  assert( u.cq.pVtab->pModule->xRename );
+  assert( memIsValid(u.cq.pName) );
+  REGISTER_TRACE(pOp->p1, u.cq.pName);
+  assert( u.cq.pName->flags & MEM_Str );
+  testcase( u.cq.pName->enc==SQLITE_UTF8 );
+  testcase( u.cq.pName->enc==SQLITE_UTF16BE );
+  testcase( u.cq.pName->enc==SQLITE_UTF16LE );
+  rc = sqlite3VdbeChangeEncoding(u.cq.pName, SQLITE_UTF8);
   if( rc==SQLITE_OK ){
-    rc = u.cp.pVtab->pModule->xRename(u.cp.pVtab, u.cp.pName->z);
-    importVtabErrMsg(p, u.cp.pVtab);
+    rc = u.cq.pVtab->pModule->xRename(u.cq.pVtab, u.cq.pName->z);
+    importVtabErrMsg(p, u.cq.pVtab);
     p->expired = 0;
   }
   break;
@@ -71841,7 +70083,7 @@ case OP_VRename: {
 ** is set to the value of the rowid for the row just inserted.
 */
 case OP_VUpdate: {
-#if 0  /* local variables moved into u.cq */
+#if 0  /* local variables moved into u.cr */
   sqlite3_vtab *pVtab;
   sqlite3_module *pModule;
   int nArg;
@@ -71849,33 +70091,33 @@ case OP_VUpdate: {
   sqlite_int64 rowid;
   Mem **apArg;
   Mem *pX;
-#endif /* local variables moved into u.cq */
+#endif /* local variables moved into u.cr */
 
   assert( pOp->p2==1        || pOp->p5==OE_Fail   || pOp->p5==OE_Rollback
        || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace
   );
-  u.cq.pVtab = pOp->p4.pVtab->pVtab;
-  u.cq.pModule = (sqlite3_module *)u.cq.pVtab->pModule;
-  u.cq.nArg = pOp->p2;
+  u.cr.pVtab = pOp->p4.pVtab->pVtab;
+  u.cr.pModule = (sqlite3_module *)u.cr.pVtab->pModule;
+  u.cr.nArg = pOp->p2;
   assert( pOp->p4type==P4_VTAB );
-  if( ALWAYS(u.cq.pModule->xUpdate) ){
+  if( ALWAYS(u.cr.pModule->xUpdate) ){
     u8 vtabOnConflict = db->vtabOnConflict;
-    u.cq.apArg = p->apArg;
-    u.cq.pX = &aMem[pOp->p3];
-    for(u.cq.i=0; u.cq.i<u.cq.nArg; u.cq.i++){
-      assert( memIsValid(u.cq.pX) );
-      memAboutToChange(p, u.cq.pX);
-      sqlite3VdbeMemStoreType(u.cq.pX);
-      u.cq.apArg[u.cq.i] = u.cq.pX;
-      u.cq.pX++;
+    u.cr.apArg = p->apArg;
+    u.cr.pX = &aMem[pOp->p3];
+    for(u.cr.i=0; u.cr.i<u.cr.nArg; u.cr.i++){
+      assert( memIsValid(u.cr.pX) );
+      memAboutToChange(p, u.cr.pX);
+      sqlite3VdbeMemStoreType(u.cr.pX);
+      u.cr.apArg[u.cr.i] = u.cr.pX;
+      u.cr.pX++;
     }
     db->vtabOnConflict = pOp->p5;
-    rc = u.cq.pModule->xUpdate(u.cq.pVtab, u.cq.nArg, u.cq.apArg, &u.cq.rowid);
+    rc = u.cr.pModule->xUpdate(u.cr.pVtab, u.cr.nArg, u.cr.apArg, &u.cr.rowid);
     db->vtabOnConflict = vtabOnConflict;
-    importVtabErrMsg(p, u.cq.pVtab);
+    importVtabErrMsg(p, u.cr.pVtab);
     if( rc==SQLITE_OK && pOp->p1 ){
-      assert( u.cq.nArg>1 && u.cq.apArg[0] && (u.cq.apArg[0]->flags&MEM_Null) );
-      db->lastRowid = lastRowid = u.cq.rowid;
+      assert( u.cr.nArg>1 && u.cr.apArg[0] && (u.cr.apArg[0]->flags&MEM_Null) );
+      db->lastRowid = lastRowid = u.cr.rowid;
     }
     if( rc==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){
       if( pOp->p5==OE_Ignore ){
@@ -71935,21 +70177,24 @@ case OP_MaxPgcnt: {            /* out2-prerelease */
 ** the UTF-8 string contained in P4 is emitted on the trace callback.
 */
 case OP_Trace: {
-#if 0  /* local variables moved into u.cr */
+#if 0  /* local variables moved into u.cs */
   char *zTrace;
   char *z;
-#endif /* local variables moved into u.cr */
+#endif /* local variables moved into u.cs */
 
-  if( db->xTrace && (u.cr.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){
-    u.cr.z = sqlite3VdbeExpandSql(p, u.cr.zTrace);
-    db->xTrace(db->pTraceArg, u.cr.z);
-    sqlite3DbFree(db, u.cr.z);
+  if( db->xTrace
+   && !p->doingRerun
+   && (u.cs.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
+  ){
+    u.cs.z = sqlite3VdbeExpandSql(p, u.cs.zTrace);
+    db->xTrace(db->pTraceArg, u.cs.z);
+    sqlite3DbFree(db, u.cs.z);
   }
 #ifdef SQLITE_DEBUG
   if( (db->flags & SQLITE_SqlTrace)!=0
-   && (u.cr.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
+   && (u.cs.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
   ){
-    sqlite3DebugPrintf("SQL-trace: %s\n", u.cr.zTrace);
+    sqlite3DebugPrintf("SQL-trace: %s\n", u.cs.zTrace);
   }
 #endif /* SQLITE_DEBUG */
   break;
@@ -72571,6 +70816,7 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
 
 typedef struct VdbeSorterIter VdbeSorterIter;
 typedef struct SorterRecord SorterRecord;
+typedef struct FileWriter FileWriter;
 
 /*
 ** NOTES ON DATA STRUCTURE USED FOR N-WAY MERGES:
@@ -72668,6 +70914,24 @@ struct VdbeSorterIter {
   sqlite3_file *pFile;            /* File iterator is reading from */
   u8 *aAlloc;                     /* Allocated space */
   u8 *aKey;                       /* Pointer to current key */
+  u8 *aBuffer;                    /* Current read buffer */
+  int nBuffer;                    /* Size of read buffer in bytes */
+};
+
+/*
+** An instance of this structure is used to organize the stream of records
+** being written to files by the merge-sort code into aligned, page-sized
+** blocks.  Doing all I/O in aligned page-sized blocks helps I/O to go
+** faster on many operating systems.
+*/
+struct FileWriter {
+  int eFWErr;                     /* Non-zero if in an error state */
+  u8 *aBuffer;                    /* Pointer to write buffer */
+  int nBuffer;                    /* Size of write buffer in bytes */
+  int iBufStart;                  /* First byte of buffer to write */
+  int iBufEnd;                    /* Last byte of buffer to write */
+  i64 iWriteOff;                  /* Offset of start of buffer in file */
+  sqlite3_file *pFile;            /* File to write to */
 };
 
 /*
@@ -72693,108 +70957,147 @@ struct SorterRecord {
 */
 static void vdbeSorterIterZero(sqlite3 *db, VdbeSorterIter *pIter){
   sqlite3DbFree(db, pIter->aAlloc);
+  sqlite3DbFree(db, pIter->aBuffer);
   memset(pIter, 0, sizeof(VdbeSorterIter));
 }
 
 /*
-** Advance iterator pIter to the next key in its PMA. Return SQLITE_OK if
-** no error occurs, or an SQLite error code if one does.
-*/
-static int vdbeSorterIterNext(
-  sqlite3 *db,                    /* Database handle (for sqlite3DbMalloc() ) */
-  VdbeSorterIter *pIter           /* Iterator to advance */
-){
-  int rc;                         /* Return Code */
-  int nRead;                      /* Number of bytes read */
-  int nRec = 0;                   /* Size of record in bytes */
-  int iOff = 0;                   /* Size of serialized size varint in bytes */
+** Read nByte bytes of data from the stream of data iterated by object p.
+** If successful, set *ppOut to point to a buffer containing the data
+** and return SQLITE_OK. Otherwise, if an error occurs, return an SQLite
+** error code.
+**
+** The buffer indicated by *ppOut may only be considered valid until the
+** next call to this function.
+*/
+static int vdbeSorterIterRead(
+  sqlite3 *db,                    /* Database handle (for malloc) */
+  VdbeSorterIter *p,              /* Iterator */
+  int nByte,                      /* Bytes of data to read */
+  u8 **ppOut                      /* OUT: Pointer to buffer containing data */
+){
+  int iBuf;                       /* Offset within buffer to read from */
+  int nAvail;                     /* Bytes of data available in buffer */
+  assert( p->aBuffer );
+
+  /* If there is no more data to be read from the buffer, read the next 
+  ** p->nBuffer bytes of data from the file into it. Or, if there are less
+  ** than p->nBuffer bytes remaining in the PMA, read all remaining data.  */
+  iBuf = p->iReadOff % p->nBuffer;
+  if( iBuf==0 ){
+    int nRead;                    /* Bytes to read from disk */
+    int rc;                       /* sqlite3OsRead() return code */
+
+    /* Determine how many bytes of data to read. */
+    if( (p->iEof - p->iReadOff) > (i64)p->nBuffer ){
+      nRead = p->nBuffer;
+    }else{
+      nRead = (int)(p->iEof - p->iReadOff);
+    }
+    assert( nRead>0 );
 
-  assert( pIter->iEof>=pIter->iReadOff );
-  if( pIter->iEof-pIter->iReadOff>5 ){
-    nRead = 5;
-  }else{
-    nRead = (int)(pIter->iEof - pIter->iReadOff);
-  }
-  if( nRead<=0 ){
-    /* This is an EOF condition */
-    vdbeSorterIterZero(db, pIter);
-    return SQLITE_OK;
+    /* Read data from the file. Return early if an error occurs. */
+    rc = sqlite3OsRead(p->pFile, p->aBuffer, nRead, p->iReadOff);
+    assert( rc!=SQLITE_IOERR_SHORT_READ );
+    if( rc!=SQLITE_OK ) return rc;
   }
+  nAvail = p->nBuffer - iBuf; 
+
+  if( nByte<=nAvail ){
+    /* The requested data is available in the in-memory buffer. In this
+    ** case there is no need to make a copy of the data, just return a 
+    ** pointer into the buffer to the caller.  */
+    *ppOut = &p->aBuffer[iBuf];
+    p->iReadOff += nByte;
+  }else{
+    /* The requested data is not all available in the in-memory buffer.
+    ** In this case, allocate space at p->aAlloc[] to copy the requested
+    ** range into. Then return a copy of pointer p->aAlloc to the caller.  */
+    int nRem;                     /* Bytes remaining to copy */
+
+    /* Extend the p->aAlloc[] allocation if required. */
+    if( p->nAlloc<nByte ){
+      int nNew = p->nAlloc*2;
+      while( nByte>nNew ) nNew = nNew*2;
+      p->aAlloc = sqlite3DbReallocOrFree(db, p->aAlloc, nNew);
+      if( !p->aAlloc ) return SQLITE_NOMEM;
+      p->nAlloc = nNew;
+    }
+
+    /* Copy as much data as is available in the buffer into the start of
+    ** p->aAlloc[].  */
+    memcpy(p->aAlloc, &p->aBuffer[iBuf], nAvail);
+    p->iReadOff += nAvail;
+    nRem = nByte - nAvail;
+
+    /* The following loop copies up to p->nBuffer bytes per iteration into
+    ** the p->aAlloc[] buffer.  */
+    while( nRem>0 ){
+      int rc;                     /* vdbeSorterIterRead() return code */
+      int nCopy;                  /* Number of bytes to copy */
+      u8 *aNext;                  /* Pointer to buffer to copy data from */
 
-  rc = sqlite3OsRead(pIter->pFile, pIter->aAlloc, nRead, pIter->iReadOff);
-  if( rc==SQLITE_OK ){
-    iOff = getVarint32(pIter->aAlloc, nRec);
-    if( (iOff+nRec)>nRead ){
-      int nRead2;                   /* Number of extra bytes to read */
-      if( (iOff+nRec)>pIter->nAlloc ){
-        int nNew = pIter->nAlloc*2;
-        while( (iOff+nRec)>nNew ) nNew = nNew*2;
-        pIter->aAlloc = sqlite3DbReallocOrFree(db, pIter->aAlloc, nNew);
-        if( !pIter->aAlloc ) return SQLITE_NOMEM;
-        pIter->nAlloc = nNew;
-      }
-  
-      nRead2 = iOff + nRec - nRead;
-      rc = sqlite3OsRead(
-          pIter->pFile, &pIter->aAlloc[nRead], nRead2, pIter->iReadOff+nRead
-      );
+      nCopy = nRem;
+      if( nRem>p->nBuffer ) nCopy = p->nBuffer;
+      rc = vdbeSorterIterRead(db, p, nCopy, &aNext);
+      if( rc!=SQLITE_OK ) return rc;
+      assert( aNext!=p->aAlloc );
+      memcpy(&p->aAlloc[nByte - nRem], aNext, nCopy);
+      nRem -= nCopy;
     }
+
+    *ppOut = p->aAlloc;
   }
 
-  assert( rc!=SQLITE_OK || nRec>0 );
-  pIter->iReadOff += iOff+nRec;
-  pIter->nKey = nRec;
-  pIter->aKey = &pIter->aAlloc[iOff];
-  return rc;
+  return SQLITE_OK;
 }
 
 /*
-** Write a single varint, value iVal, to file-descriptor pFile. Return
-** SQLITE_OK if successful, or an SQLite error code if some error occurs.
-**
-** The value of *piOffset when this function is called is used as the byte
-** offset in file pFile to write to. Before returning, *piOffset is 
-** incremented by the number of bytes written.
+** Read a varint from the stream of data accessed by p. Set *pnOut to
+** the value read.
 */
-static int vdbeSorterWriteVarint(
-  sqlite3_file *pFile,            /* File to write to */
-  i64 iVal,                       /* Value to write as a varint */
-  i64 *piOffset                   /* IN/OUT: Write offset in file pFile */
-){
-  u8 aVarint[9];                  /* Buffer large enough for a varint */
-  int nVarint;                    /* Number of used bytes in varint */
-  int rc;                         /* Result of write() call */
+static int vdbeSorterIterVarint(sqlite3 *db, VdbeSorterIter *p, u64 *pnOut){
+  int iBuf;
 
-  nVarint = sqlite3PutVarint(aVarint, iVal);
-  rc = sqlite3OsWrite(pFile, aVarint, nVarint, *piOffset);
-  *piOffset += nVarint;
+  iBuf = p->iReadOff % p->nBuffer;
+  if( iBuf && (p->nBuffer-iBuf)>=9 ){
+    p->iReadOff += sqlite3GetVarint(&p->aBuffer[iBuf], pnOut);
+  }else{
+    u8 aVarint[16], *a;
+    int i = 0, rc;
+    do{
+      rc = vdbeSorterIterRead(db, p, 1, &a);
+      if( rc ) return rc;
+      aVarint[(i++)&0xf] = a[0];
+    }while( (a[0]&0x80)!=0 );
+    sqlite3GetVarint(aVarint, pnOut);
+  }
 
-  return rc;
+  return SQLITE_OK;
 }
 
+
 /*
-** Read a single varint from file-descriptor pFile. Return SQLITE_OK if
-** successful, or an SQLite error code if some error occurs.
-**
-** The value of *piOffset when this function is called is used as the
-** byte offset in file pFile from whence to read the varint. If successful
-** (i.e. if no IO error occurs), then *piOffset is set to the offset of
-** the first byte past the end of the varint before returning. *piVal is
-** set to the integer value read. If an error occurs, the final values of
-** both *piOffset and *piVal are undefined.
+** Advance iterator pIter to the next key in its PMA. Return SQLITE_OK if
+** no error occurs, or an SQLite error code if one does.
 */
-static int vdbeSorterReadVarint(
-  sqlite3_file *pFile,            /* File to read from */
-  i64 *piOffset,                  /* IN/OUT: Read offset in pFile */
-  i64 *piVal                      /* OUT: Value read from file */
+static int vdbeSorterIterNext(
+  sqlite3 *db,                    /* Database handle (for sqlite3DbMalloc() ) */
+  VdbeSorterIter *pIter           /* Iterator to advance */
 ){
-  u8 aVarint[9];                  /* Buffer large enough for a varint */
-  i64 iOff = *piOffset;           /* Offset in file to read from */
-  int rc;                         /* Return code */
+  int rc;                         /* Return Code */
+  u64 nRec = 0;                   /* Size of record in bytes */
+
+  if( pIter->iReadOff>=pIter->iEof ){
+    /* This is an EOF condition */
+    vdbeSorterIterZero(db, pIter);
+    return SQLITE_OK;
+  }
 
-  rc = sqlite3OsRead(pFile, aVarint, 9, iOff);
+  rc = vdbeSorterIterVarint(db, pIter, &nRec);
   if( rc==SQLITE_OK ){
-    *piOffset += getVarint(aVarint, (u64 *)piVal);
+    pIter->nKey = (int)nRec;
+    rc = vdbeSorterIterRead(db, pIter, (int)nRec, &pIter->aKey);
   }
 
   return rc;
@@ -72808,27 +71111,52 @@ static int vdbeSorterReadVarint(
 */
 static int vdbeSorterIterInit(
   sqlite3 *db,                    /* Database handle */
-  VdbeSorter *pSorter,            /* Sorter object */
+  const VdbeSorter *pSorter,      /* Sorter object */
   i64 iStart,                     /* Start offset in pFile */
   VdbeSorterIter *pIter,          /* Iterator to populate */
   i64 *pnByte                     /* IN/OUT: Increment this value by PMA size */
 ){
-  int rc;
+  int rc = SQLITE_OK;
+  int nBuf;
+
+  nBuf = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
 
   assert( pSorter->iWriteOff>iStart );
   assert( pIter->aAlloc==0 );
+  assert( pIter->aBuffer==0 );
   pIter->pFile = pSorter->pTemp1;
   pIter->iReadOff = iStart;
   pIter->nAlloc = 128;
   pIter->aAlloc = (u8 *)sqlite3DbMallocRaw(db, pIter->nAlloc);
-  if( !pIter->aAlloc ){
+  pIter->nBuffer = nBuf;
+  pIter->aBuffer = (u8 *)sqlite3DbMallocRaw(db, nBuf);
+
+  if( !pIter->aBuffer ){
     rc = SQLITE_NOMEM;
   }else{
-    i64 nByte;                         /* Total size of PMA in bytes */
-    rc = vdbeSorterReadVarint(pSorter->pTemp1, &pIter->iReadOff, &nByte);
-    *pnByte += nByte;
-    pIter->iEof = pIter->iReadOff + nByte;
+    int iBuf;
+
+    iBuf = iStart % nBuf;
+    if( iBuf ){
+      int nRead = nBuf - iBuf;
+      if( (iStart + nRead) > pSorter->iWriteOff ){
+        nRead = (int)(pSorter->iWriteOff - iStart);
+      }
+      rc = sqlite3OsRead(
+          pSorter->pTemp1, &pIter->aBuffer[iBuf], nRead, iStart
+      );
+      assert( rc!=SQLITE_IOERR_SHORT_READ );
+    }
+
+    if( rc==SQLITE_OK ){
+      u64 nByte;                       /* Size of PMA in bytes */
+      pIter->iEof = pSorter->iWriteOff;
+      rc = vdbeSorterIterVarint(db, pIter, &nByte);
+      pIter->iEof = pIter->iReadOff + nByte;
+      *pnByte += nByte;
+    }
   }
+
   if( rc==SQLITE_OK ){
     rc = vdbeSorterIterNext(db, pIter);
   }
@@ -72852,10 +71180,10 @@ static int vdbeSorterIterInit(
 ** has been allocated and contains an unpacked record that is used as key2.
 */
 static void vdbeSorterCompare(
-  VdbeCursor *pCsr,               /* Cursor object (for pKeyInfo) */
+  const VdbeCursor *pCsr,         /* Cursor object (for pKeyInfo) */
   int bOmitRowid,                 /* Ignore rowid field at end of keys */
-  void *pKey1, int nKey1,         /* Left side of comparison */
-  void *pKey2, int nKey2,         /* Right side of comparison */
+  const void *pKey1, int nKey1,   /* Left side of comparison */
+  const void *pKey2, int nKey2,   /* Right side of comparison */
   int *pRes                       /* OUT: Result of comparison */
 ){
   KeyInfo *pKeyInfo = pCsr->pKeyInfo;
@@ -72887,7 +71215,7 @@ static void vdbeSorterCompare(
 ** multiple b-tree segments. Parameter iOut is the index of the aTree[] 
 ** value to recalculate.
 */
-static int vdbeSorterDoCompare(VdbeCursor *pCsr, int iOut){
+static int vdbeSorterDoCompare(const VdbeCursor *pCsr, int iOut){
   VdbeSorter *pSorter = pCsr->pSorter;
   int i1;
   int i2;
@@ -73013,7 +71341,7 @@ static int vdbeSorterOpenTempFile(sqlite3 *db, sqlite3_file **ppFile){
 ** Set *ppOut to the head of the new list.
 */
 static void vdbeSorterMerge(
-  VdbeCursor *pCsr,               /* For pKeyInfo */
+  const VdbeCursor *pCsr,         /* For pKeyInfo */
   SorterRecord *p1,               /* First list to merge */
   SorterRecord *p2,               /* Second list to merge */
   SorterRecord **ppOut            /* OUT: Head of merged list */
@@ -73047,7 +71375,7 @@ static void vdbeSorterMerge(
 ** if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if an error
 ** occurs.
 */
-static int vdbeSorterSort(VdbeCursor *pCsr){
+static int vdbeSorterSort(const VdbeCursor *pCsr){
   int i;
   SorterRecord **aSlot;
   SorterRecord *p;
@@ -73080,6 +71408,91 @@ static int vdbeSorterSort(VdbeCursor *pCsr){
   return SQLITE_OK;
 }
 
+/*
+** Initialize a file-writer object.
+*/
+static void fileWriterInit(
+  sqlite3 *db,                    /* Database (for malloc) */
+  sqlite3_file *pFile,            /* File to write to */
+  FileWriter *p,                  /* Object to populate */
+  i64 iStart                      /* Offset of pFile to begin writing at */
+){
+  int nBuf = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
+
+  memset(p, 0, sizeof(FileWriter));
+  p->aBuffer = (u8 *)sqlite3DbMallocRaw(db, nBuf);
+  if( !p->aBuffer ){
+    p->eFWErr = SQLITE_NOMEM;
+  }else{
+    p->iBufEnd = p->iBufStart = (iStart % nBuf);
+    p->iWriteOff = iStart - p->iBufStart;
+    p->nBuffer = nBuf;
+    p->pFile = pFile;
+  }
+}
+
+/*
+** Write nData bytes of data to the file-write object. Return SQLITE_OK
+** if successful, or an SQLite error code if an error occurs.
+*/
+static void fileWriterWrite(FileWriter *p, u8 *pData, int nData){
+  int nRem = nData;
+  while( nRem>0 && p->eFWErr==0 ){
+    int nCopy = nRem;
+    if( nCopy>(p->nBuffer - p->iBufEnd) ){
+      nCopy = p->nBuffer - p->iBufEnd;
+    }
+
+    memcpy(&p->aBuffer[p->iBufEnd], &pData[nData-nRem], nCopy);
+    p->iBufEnd += nCopy;
+    if( p->iBufEnd==p->nBuffer ){
+      p->eFWErr = sqlite3OsWrite(p->pFile, 
+          &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, 
+          p->iWriteOff + p->iBufStart
+      );
+      p->iBufStart = p->iBufEnd = 0;
+      p->iWriteOff += p->nBuffer;
+    }
+    assert( p->iBufEnd<p->nBuffer );
+
+    nRem -= nCopy;
+  }
+}
+
+/*
+** Flush any buffered data to disk and clean up the file-writer object.
+** The results of using the file-writer after this call are undefined.
+** Return SQLITE_OK if flushing the buffered data succeeds or is not 
+** required. Otherwise, return an SQLite error code.
+**
+** Before returning, set *piEof to the offset immediately following the
+** last byte written to the file.
+*/
+static int fileWriterFinish(sqlite3 *db, FileWriter *p, i64 *piEof){
+  int rc;
+  if( p->eFWErr==0 && ALWAYS(p->aBuffer) && p->iBufEnd>p->iBufStart ){
+    p->eFWErr = sqlite3OsWrite(p->pFile, 
+        &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, 
+        p->iWriteOff + p->iBufStart
+    );
+  }
+  *piEof = (p->iWriteOff + p->iBufEnd);
+  sqlite3DbFree(db, p->aBuffer);
+  rc = p->eFWErr;
+  memset(p, 0, sizeof(FileWriter));
+  return rc;
+}
+
+/*
+** Write value iVal encoded as a varint to the file-write object. Return 
+** SQLITE_OK if successful, or an SQLite error code if an error occurs.
+*/
+static void fileWriterWriteVarint(FileWriter *p, u64 iVal){
+  int nByte; 
+  u8 aByte[10];
+  nByte = sqlite3PutVarint(aByte, iVal);
+  fileWriterWrite(p, aByte, nByte);
+}
 
 /*
 ** Write the current contents of the in-memory linked-list to a PMA. Return
@@ -73094,9 +71507,12 @@ static int vdbeSorterSort(VdbeCursor *pCsr){
 **       Each record consists of a varint followed by a blob of data (the 
 **       key). The varint is the number of bytes in the blob of data.
 */
-static int vdbeSorterListToPMA(sqlite3 *db, VdbeCursor *pCsr){
+static int vdbeSorterListToPMA(sqlite3 *db, const VdbeCursor *pCsr){
   int rc = SQLITE_OK;             /* Return code */
   VdbeSorter *pSorter = pCsr->pSorter;
+  FileWriter writer;
+
+  memset(&writer, 0, sizeof(FileWriter));
 
   if( pSorter->nInMemory==0 ){
     assert( pSorter->pRecord==0 );
@@ -73114,39 +71530,20 @@ static int vdbeSorterListToPMA(sqlite3 *db, VdbeCursor *pCsr){
   }
 
   if( rc==SQLITE_OK ){
-    i64 iOff = pSorter->iWriteOff;
     SorterRecord *p;
     SorterRecord *pNext = 0;
-    static const char eightZeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
 
+    fileWriterInit(db, pSorter->pTemp1, &writer, pSorter->iWriteOff);
     pSorter->nPMA++;
-    rc = vdbeSorterWriteVarint(pSorter->pTemp1, pSorter->nInMemory, &iOff);
-    for(p=pSorter->pRecord; rc==SQLITE_OK && p; p=pNext){
+    fileWriterWriteVarint(&writer, pSorter->nInMemory);
+    for(p=pSorter->pRecord; p; p=pNext){
       pNext = p->pNext;
-      rc = vdbeSorterWriteVarint(pSorter->pTemp1, p->nVal, &iOff);
-
-      if( rc==SQLITE_OK ){
-        rc = sqlite3OsWrite(pSorter->pTemp1, p->pVal, p->nVal, iOff);
-        iOff += p->nVal;
-      }
-
+      fileWriterWriteVarint(&writer, p->nVal);
+      fileWriterWrite(&writer, p->pVal, p->nVal);
       sqlite3DbFree(db, p);
     }
-
-    /* This assert verifies that unless an error has occurred, the size of 
-    ** the PMA on disk is the same as the expected size stored in
-    ** pSorter->nInMemory. */ 
-    assert( rc!=SQLITE_OK || pSorter->nInMemory==(
-          iOff-pSorter->iWriteOff-sqlite3VarintLen(pSorter->nInMemory)
-    ));
-
-    pSorter->iWriteOff = iOff;
-    if( rc==SQLITE_OK ){
-      /* Terminate each file with 8 extra bytes so that from any offset
-      ** in the file we can always read 9 bytes without a SHORT_READ error */
-      rc = sqlite3OsWrite(pSorter->pTemp1, eightZeros, 8, iOff);
-    }
     pSorter->pRecord = p;
+    rc = fileWriterFinish(db, &writer, &pSorter->iWriteOff);
   }
 
   return rc;
@@ -73157,7 +71554,7 @@ static int vdbeSorterListToPMA(sqlite3 *db, VdbeCursor *pCsr){
 */
 SQLITE_PRIVATE int sqlite3VdbeSorterWrite(
   sqlite3 *db,                    /* Database handle */
-  VdbeCursor *pCsr,               /* Sorter cursor */
+  const VdbeCursor *pCsr,               /* Sorter cursor */
   Mem *pVal                       /* Memory cell containing record */
 ){
   VdbeSorter *pSorter = pCsr->pSorter;
@@ -73191,8 +71588,14 @@ SQLITE_PRIVATE int sqlite3VdbeSorterWrite(
         (pSorter->nInMemory>pSorter->mxPmaSize)
      || (pSorter->nInMemory>pSorter->mnPmaSize && sqlite3HeapNearlyFull())
   )){
+#ifdef SQLITE_DEBUG
+    i64 nExpect = pSorter->iWriteOff
+                + sqlite3VarintLen(pSorter->nInMemory)
+                + pSorter->nInMemory;
+#endif
     rc = vdbeSorterListToPMA(db, pCsr);
     pSorter->nInMemory = 0;
+    assert( rc!=SQLITE_OK || (nExpect==pSorter->iWriteOff) );
   }
 
   return rc;
@@ -73203,7 +71606,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterWrite(
 */
 static int vdbeSorterInitMerge(
   sqlite3 *db,                    /* Database handle */
-  VdbeCursor *pCsr,               /* Cursor handle for this sorter */
+  const VdbeCursor *pCsr,         /* Cursor handle for this sorter */
   i64 *pnByte                     /* Sum of bytes in all opened PMAs */
 ){
   VdbeSorter *pSorter = pCsr->pSorter;
@@ -73233,7 +71636,7 @@ static int vdbeSorterInitMerge(
 ** Once the sorter has been populated, this function is called to prepare
 ** for iterating through its contents in sorted order.
 */
-SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){
+SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){
   VdbeSorter *pSorter = pCsr->pSorter;
   int rc;                         /* Return code */
   sqlite3_file *pTemp2 = 0;       /* Second temp file to use */
@@ -73253,7 +71656,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *p
     return vdbeSorterSort(pCsr);
   }
 
-  /* Write the current b-tree to a PMA. Close the b-tree cursor. */
+  /* Write the current in-memory list to a PMA. */
   rc = vdbeSorterListToPMA(db, pCsr);
   if( rc!=SQLITE_OK ) return rc;
 
@@ -73275,8 +71678,12 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *p
         rc==SQLITE_OK && iNew*SORTER_MAX_MERGE_COUNT<pSorter->nPMA; 
         iNew++
     ){
+      int rc2;                    /* Return code from fileWriterFinish() */
+      FileWriter writer;          /* Object used to write to disk */
       i64 nWrite;                 /* Number of bytes in new PMA */
 
+      memset(&writer, 0, sizeof(FileWriter));
+
       /* If there are SORTER_MAX_MERGE_COUNT or less PMAs in file pTemp1,
       ** initialize an iterator for each of them and break out of the loop.
       ** These iterators will be incrementally merged as the VDBE layer calls
@@ -73298,23 +71705,20 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *p
         rc = vdbeSorterOpenTempFile(db, &pTemp2);
       }
 
-      if( rc==SQLITE_OK ){
-        rc = vdbeSorterWriteVarint(pTemp2, nWrite, &iWrite2);
-      }
-
       if( rc==SQLITE_OK ){
         int bEof = 0;
+        fileWriterInit(db, pTemp2, &writer, iWrite2);
+        fileWriterWriteVarint(&writer, nWrite);
         while( rc==SQLITE_OK && bEof==0 ){
-          int nToWrite;
           VdbeSorterIter *pIter = &pSorter->aIter[ pSorter->aTree[1] ];
           assert( pIter->pFile );
-          nToWrite = pIter->nKey + sqlite3VarintLen(pIter->nKey);
-          rc = sqlite3OsWrite(pTemp2, pIter->aAlloc, nToWrite, iWrite2);
-          iWrite2 += nToWrite;
-          if( rc==SQLITE_OK ){
-            rc = sqlite3VdbeSorterNext(db, pCsr, &bEof);
-          }
+
+          fileWriterWriteVarint(&writer, pIter->nKey);
+          fileWriterWrite(&writer, pIter->aKey, pIter->nKey);
+          rc = sqlite3VdbeSorterNext(db, pCsr, &bEof);
         }
+        rc2 = fileWriterFinish(db, &writer, &iWrite2);
+        if( rc==SQLITE_OK ) rc = rc2;
       }
     }
 
@@ -73341,7 +71745,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *p
 /*
 ** Advance to the next element in the sorter.
 */
-SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){
+SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){
   VdbeSorter *pSorter = pCsr->pSorter;
   int rc;                         /* Return code */
 
@@ -73371,7 +71775,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, VdbeCursor *pCsr, int *pbE
 ** current key.
 */
 static void *vdbeSorterRowkey(
-  VdbeSorter *pSorter,            /* Sorter object */
+  const VdbeSorter *pSorter,      /* Sorter object */
   int *pnKey                      /* OUT: Size of current key in bytes */
 ){
   void *pKey;
@@ -73390,7 +71794,7 @@ static void *vdbeSorterRowkey(
 /*
 ** Copy the current sorter key into the memory cell pOut.
 */
-SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *pCsr, Mem *pOut){
+SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){
   VdbeSorter *pSorter = pCsr->pSorter;
   void *pKey; int nKey;           /* Sorter key to copy into pOut */
 
@@ -73416,7 +71820,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *pCsr, Mem *pOut){
 ** key.
 */
 SQLITE_PRIVATE int sqlite3VdbeSorterCompare(
-  VdbeCursor *pCsr,               /* Sorter cursor */
+  const VdbeCursor *pCsr,         /* Sorter cursor */
   Mem *pVal,                      /* Value to compare to current sorter key */
   int *pRes                       /* OUT: Result of comparison */
 ){
@@ -73661,6 +72065,16 @@ SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *p){
   return createFile((JournalFile *)p);
 }
 
+/*
+** The file-handle passed as the only argument is guaranteed to be an open
+** file. It may or may not be of class JournalFile. If the file is a
+** JournalFile, and the underlying file on disk has not yet been opened,
+** return 0. Otherwise, return 1.
+*/
+SQLITE_PRIVATE int sqlite3JournalExists(sqlite3_file *p){
+  return (p->pMethods!=&JournalFileMethods || ((JournalFile *)p)->pReal!=0);
+}
+
 /* 
 ** Return the number of bytes required to store a JournalFile that uses vfs
 ** pVfs to create the underlying on-disk files.
@@ -74059,13 +72473,19 @@ SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){
   int rc;
   if( p==0 || pWalker->xSelectCallback==0 ) return WRC_Continue;
   rc = WRC_Continue;
-  while( p  ){
+  pWalker->walkerDepth++;
+  while( p ){
     rc = pWalker->xSelectCallback(pWalker, p);
     if( rc ) break;
-    if( sqlite3WalkSelectExpr(pWalker, p) ) return WRC_Abort;
-    if( sqlite3WalkSelectFrom(pWalker, p) ) return WRC_Abort;
+    if( sqlite3WalkSelectExpr(pWalker, p)
+     || sqlite3WalkSelectFrom(pWalker, p)
+    ){
+      pWalker->walkerDepth--;
+      return WRC_Abort;
+    }
     p = p->pPrior;
   }
+  pWalker->walkerDepth--;
   return rc & WRC_Abort;
 }
 
@@ -74090,6 +72510,29 @@ SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){
 /* #include <stdlib.h> */
 /* #include <string.h> */
 
+/*
+** Walk the expression tree pExpr and increase the aggregate function
+** depth (the Expr.op2 field) by N on every TK_AGG_FUNCTION node.
+** This needs to occur when copying a TK_AGG_FUNCTION node from an
+** outer query into an inner subquery.
+**
+** incrAggFunctionDepth(pExpr,n) is the main routine.  incrAggDepth(..)
+** is a helper function - a callback for the tree walker.
+*/
+static int incrAggDepth(Walker *pWalker, Expr *pExpr){
+  if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.i;
+  return WRC_Continue;
+}
+static void incrAggFunctionDepth(Expr *pExpr, int N){
+  if( N>0 ){
+    Walker w;
+    memset(&w, 0, sizeof(w));
+    w.xExprCallback = incrAggDepth;
+    w.u.i = N;
+    sqlite3WalkExpr(&w, pExpr);
+  }
+}
+
 /*
 ** Turn the pExpr expression into an alias for the iCol-th column of the
 ** result set in pEList.
@@ -74116,13 +72559,29 @@ SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){
 ** 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...
+**
+** If the reference is followed by a COLLATE operator, then make sure
+** the COLLATE operator is preserved.  For example:
+**
+**     SELECT a+b, c+d FROM t1 ORDER BY 1 COLLATE nocase;
+**
+** Should be transformed into:
+**
+**     SELECT a+b, c+d FROM t1 ORDER BY (a+b) COLLATE nocase;
+**
+** The nSubquery parameter specifies how many levels of subquery the
+** alias is removed from the original expression.  The usually value is
+** zero but it might be more if the alias is contained within a subquery
+** of the original expression.  The Expr.op2 field of TK_AGG_FUNCTION
+** structures must be increased by the nSubquery amount.
 */
 static void resolveAlias(
   Parse *pParse,         /* Parsing context */
   ExprList *pEList,      /* A result set */
   int iCol,              /* A column in the result set.  0..pEList->nExpr-1 */
   Expr *pExpr,           /* Transform this into an alias to the result set */
-  const char *zType      /* "GROUP" or "ORDER" or "" */
+  const char *zType,     /* "GROUP" or "ORDER" or "" */
+  int nSubquery          /* Number of subqueries that the label is moving */
 ){
   Expr *pOrig;           /* The iCol-th column of the result set */
   Expr *pDup;            /* Copy of pOrig */
@@ -74133,40 +72592,36 @@ static void resolveAlias(
   assert( pOrig!=0 );
   assert( pOrig->flags & EP_Resolved );
   db = pParse->db;
+  pDup = sqlite3ExprDup(db, pOrig, 0);
+  if( pDup==0 ) return;
   if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){
-    pDup = sqlite3ExprDup(db, pOrig, 0);
+    incrAggFunctionDepth(pDup, nSubquery);
     pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0);
     if( pDup==0 ) return;
     if( pEList->a[iCol].iAlias==0 ){
       pEList->a[iCol].iAlias = (u16)(++pParse->nAlias);
     }
     pDup->iTable = pEList->a[iCol].iAlias;
-  }else if( ExprHasProperty(pOrig, EP_IntValue) || pOrig->u.zToken==0 ){
-    pDup = sqlite3ExprDup(db, pOrig, 0);
-    if( pDup==0 ) return;
-  }else{
-    char *zToken = pOrig->u.zToken;
-    assert( zToken!=0 );
-    pOrig->u.zToken = 0;
-    pDup = sqlite3ExprDup(db, pOrig, 0);
-    pOrig->u.zToken = zToken;
-    if( pDup==0 ) return;
-    assert( (pDup->flags & (EP_Reduced|EP_TokenOnly))==0 );
-    pDup->flags2 |= EP2_MallocedToken;
-    pDup->u.zToken = sqlite3DbStrDup(db, zToken);
   }
-  if( pExpr->flags & EP_ExpCollate ){
-    pDup->pColl = pExpr->pColl;
-    pDup->flags |= EP_ExpCollate;
+  if( pExpr->op==TK_COLLATE ){
+    pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
   }
 
   /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This 
   ** prevents ExprDelete() from deleting the Expr structure itself,
   ** allowing it to be repopulated by the memcpy() on the following line.
+  ** The pExpr->u.zToken might point into memory that will be freed by the
+  ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to
+  ** make a copy of the token before doing the sqlite3DbFree().
   */
   ExprSetProperty(pExpr, EP_Static);
   sqlite3ExprDelete(db, pExpr);
   memcpy(pExpr, pDup, sizeof(*pExpr));
+  if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){
+    assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 );
+    pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken);
+    pExpr->flags2 |= EP2_MallocedToken;
+  }
   sqlite3DbFree(db, pDup);
 }
 
@@ -74223,9 +72678,10 @@ static int lookupName(
   NameContext *pNC,    /* The name context used to resolve the name */
   Expr *pExpr          /* Make this EXPR node point to the selected column */
 ){
-  int i, j;            /* Loop counters */
+  int i, j;                         /* Loop counters */
   int cnt = 0;                      /* Number of matching column names */
   int cntTab = 0;                   /* Number of matching table names */
+  int nSubquery = 0;                /* How many levels of subquery */
   sqlite3 *db = pParse->db;         /* The database connection */
   struct SrcList_item *pItem;       /* Use for looping over pSrcList items */
   struct SrcList_item *pMatch = 0;  /* The matching pSrcList item */
@@ -74235,7 +72691,7 @@ static int lookupName(
 
   assert( pNC );     /* the name context cannot be NULL. */
   assert( zCol );    /* The Z in X.Y.Z cannot be NULL */
-  assert( ~ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
+  assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
 
   /* Initialize the node to no-match */
   pExpr->iTable = -1;
@@ -74387,7 +72843,7 @@ static int lookupName(
             sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
             return WRC_Abort;
           }
-          resolveAlias(pParse, pEList, j, pExpr, "");
+          resolveAlias(pParse, pEList, j, pExpr, "", nSubquery);
           cnt = 1;
           pMatch = 0;
           assert( zTab==0 && zDb==0 );
@@ -74401,6 +72857,7 @@ static int lookupName(
     */
     if( cnt==0 ){
       pNC = pNC->pNext;
+      nSubquery++;
     }
   }
 
@@ -74640,13 +73097,19 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
              nId, zId);
         pNC->nErr++;
       }
+      if( is_agg ) pNC->ncFlags &= ~NC_AllowAgg;
+      sqlite3WalkExprList(pWalker, pList);
       if( is_agg ){
+        NameContext *pNC2 = pNC;
         pExpr->op = TK_AGG_FUNCTION;
-        pNC->ncFlags |= NC_HasAgg;
+        pExpr->op2 = 0;
+        while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){
+          pExpr->op2++;
+          pNC2 = pNC2->pNext;
+        }
+        if( pNC2 ) pNC2->ncFlags |= NC_HasAgg;
+        pNC->ncFlags |= NC_AllowAgg;
       }
-      if( is_agg ) pNC->ncFlags &= ~NC_AllowAgg;
-      sqlite3WalkExprList(pWalker, pList);
-      if( is_agg ) pNC->ncFlags |= NC_AllowAgg;
       /* FIX ME:  Compute pExpr->affinity based on the expected return
       ** type of the function 
       */
@@ -74845,7 +73308,7 @@ static int resolveCompoundOrderBy(
       int iCol = -1;
       Expr *pE, *pDup;
       if( pItem->done ) continue;
-      pE = pItem->pExpr;
+      pE = sqlite3ExprSkipCollate(pItem->pExpr);
       if( sqlite3ExprIsInteger(pE, &iCol) ){
         if( iCol<=0 || iCol>pEList->nExpr ){
           resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr);
@@ -74863,14 +73326,20 @@ static int resolveCompoundOrderBy(
         }
       }
       if( iCol>0 ){
-        CollSeq *pColl = pE->pColl;
-        int flags = pE->flags & EP_ExpCollate;
+        /* Convert the ORDER BY term into an integer column number iCol,
+        ** taking care to preserve the COLLATE clause if it exists */
+        Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
+        if( pNew==0 ) return 1;
+        pNew->flags |= EP_IntValue;
+        pNew->u.iValue = iCol;
+        if( pItem->pExpr==pE ){
+          pItem->pExpr = pNew;
+        }else{
+          assert( pItem->pExpr->op==TK_COLLATE );
+          assert( pItem->pExpr->pLeft==pE );
+          pItem->pExpr->pLeft = pNew;
+        }
         sqlite3ExprDelete(db, pE);
-        pItem->pExpr = pE = sqlite3Expr(db, TK_INTEGER, 0);
-        if( pE==0 ) return 1;
-        pE->pColl = pColl;
-        pE->flags |= EP_IntValue | flags;
-        pE->u.iValue = iCol;
         pItem->iOrderByCol = (u16)iCol;
         pItem->done = 1;
       }else{
@@ -74925,7 +73394,7 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(
         resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr);
         return 1;
       }
-      resolveAlias(pParse, pEList, pItem->iOrderByCol-1, pItem->pExpr, zType);
+      resolveAlias(pParse, pEList, pItem->iOrderByCol-1, pItem->pExpr, zType,0);
     }
   }
   return 0;
@@ -74975,11 +73444,11 @@ static int resolveOrderGroupBy(
       pItem->iOrderByCol = (u16)iCol;
       continue;
     }
-    if( sqlite3ExprIsInteger(pE, &iCol) ){
+    if( sqlite3ExprIsInteger(sqlite3ExprSkipCollate(pE), &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 */
-      if( iCol<1 ){
+      if( iCol<1 || iCol>0xffff ){
         resolveOutOfRangeError(pParse, zType, i+1, nResult);
         return 1;
       }
@@ -75333,7 +73802,9 @@ SQLITE_PRIVATE void sqlite3ResolveSelectNames(
 ** SELECT * FROM t1 WHERE (select a from t1);
 */
 SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
-  int op = pExpr->op;
+  int op;
+  pExpr = sqlite3ExprSkipCollate(pExpr);
+  op = pExpr->op;
   if( op==TK_SELECT ){
     assert( pExpr->flags&EP_xIsSelect );
     return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
@@ -75358,66 +73829,94 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
 }
 
 /*
-** Set the explicit collating sequence for an expression to the
-** collating sequence supplied in the second argument.
+** Set the collating sequence for expression pExpr to be the collating
+** sequence named by pToken.   Return a pointer to a new Expr node that
+** implements the COLLATE operator.
+**
+** If a memory allocation error occurs, that fact is recorded in pParse->db
+** and the pExpr parameter is returned unchanged.
 */
-SQLITE_PRIVATE Expr *sqlite3ExprSetColl(Expr *pExpr, CollSeq *pColl){
-  if( pExpr && pColl ){
-    pExpr->pColl = pColl;
-    pExpr->flags |= EP_ExpCollate;
+SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr *pExpr, Token *pCollName){
+  if( pCollName->n>0 ){
+    Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1);
+    if( pNew ){
+      pNew->pLeft = pExpr;
+      pNew->flags |= EP_Collate;
+      pExpr = pNew;
+    }
   }
   return pExpr;
 }
+SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){
+  Token s;
+  assert( zC!=0 );
+  s.z = zC;
+  s.n = sqlite3Strlen30(s.z);
+  return sqlite3ExprAddCollateToken(pParse, pExpr, &s);
+}
 
 /*
-** Set the collating sequence for expression pExpr to be the collating
-** sequence named by pToken.   Return a pointer to the revised expression.
-** The collating sequence is marked as "explicit" using the EP_ExpCollate
-** flag.  An explicit collating sequence will override implicit
-** collating sequences.
+** Skip over any TK_COLLATE and/or TK_AS operators at the root of
+** an expression.
 */
-SQLITE_PRIVATE Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr *pExpr, Token *pCollName){
-  char *zColl = 0;            /* Dequoted name of collation sequence */
-  CollSeq *pColl;
-  sqlite3 *db = pParse->db;
-  zColl = sqlite3NameFromToken(db, pCollName);
-  pColl = sqlite3LocateCollSeq(pParse, zColl);
-  sqlite3ExprSetColl(pExpr, pColl);
-  sqlite3DbFree(db, zColl);
+SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){
+  while( pExpr && (pExpr->op==TK_COLLATE || pExpr->op==TK_AS) ){
+    pExpr = pExpr->pLeft;
+  }
   return pExpr;
 }
 
 /*
-** Return the default collation sequence for the expression pExpr. If
-** there is no default collation type, return 0.
+** Return the collation sequence for the expression pExpr. If
+** there is no defined collating sequence, return NULL.
+**
+** The collating sequence might be determined by a COLLATE operator
+** or by the presence of a column with a defined collating sequence.
+** COLLATE operators take first precedence.  Left operands take
+** precedence over right operands.
 */
 SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
+  sqlite3 *db = pParse->db;
   CollSeq *pColl = 0;
   Expr *p = pExpr;
   while( p ){
-    int op;
-    pColl = p->pColl;
-    if( pColl ) break;
-    op = p->op;
-    if( p->pTab!=0 && (
-        op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER || op==TK_TRIGGER
-    )){
+    int op = p->op;
+    if( op==TK_CAST || op==TK_UPLUS ){
+      p = p->pLeft;
+      continue;
+    }
+    assert( op!=TK_REGISTER || p->op2!=TK_COLLATE );
+    if( op==TK_COLLATE ){
+      if( db->init.busy ){
+        /* Do not report errors when parsing while the schema */
+        pColl = sqlite3FindCollSeq(db, ENC(db), p->u.zToken, 0);
+      }else{
+        pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
+      }
+      break;
+    }
+    if( p->pTab!=0
+     && (op==TK_AGG_COLUMN || op==TK_COLUMN
+          || op==TK_REGISTER || op==TK_TRIGGER)
+    ){
       /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
       ** a TK_COLUMN but was previously evaluated and cached in a register */
-      const char *zColl;
       int j = p->iColumn;
       if( j>=0 ){
-        sqlite3 *db = pParse->db;
-        zColl = p->pTab->aCol[j].zColl;
+        const char *zColl = p->pTab->aCol[j].zColl;
         pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
-        pExpr->pColl = pColl;
       }
       break;
     }
-    if( op!=TK_CAST && op!=TK_UPLUS ){
+    if( p->flags & EP_Collate ){
+      if( ALWAYS(p->pLeft) && (p->pLeft->flags & EP_Collate)!=0 ){
+        p = p->pLeft;
+      }else{
+        p = p->pRight;
+      }
+    }else{
       break;
     }
-    p = p->pLeft;
   }
   if( sqlite3CheckCollSeq(pParse, pColl) ){ 
     pColl = 0;
@@ -75521,12 +74020,10 @@ SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(
 ){
   CollSeq *pColl;
   assert( pLeft );
-  if( pLeft->flags & EP_ExpCollate ){
-    assert( pLeft->pColl );
-    pColl = pLeft->pColl;
-  }else if( pRight && pRight->flags & EP_ExpCollate ){
-    assert( pRight->pColl );
-    pColl = pRight->pColl;
+  if( pLeft->flags & EP_Collate ){
+    pColl = sqlite3ExprCollSeq(pParse, pLeft);
+  }else if( pRight && (pRight->flags & EP_Collate)!=0 ){
+    pColl = sqlite3ExprCollSeq(pParse, pRight);
   }else{
     pColl = sqlite3ExprCollSeq(pParse, pLeft);
     if( !pColl ){
@@ -75756,17 +74253,11 @@ SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(
   }else{
     if( pRight ){
       pRoot->pRight = pRight;
-      if( pRight->flags & EP_ExpCollate ){
-        pRoot->flags |= EP_ExpCollate;
-        pRoot->pColl = pRight->pColl;
-      }
+      pRoot->flags |= EP_Collate & pRight->flags;
     }
     if( pLeft ){
       pRoot->pLeft = pLeft;
-      if( pLeft->flags & EP_ExpCollate ){
-        pRoot->flags |= EP_ExpCollate;
-        pRoot->pColl = pLeft->pColl;
-      }
+      pRoot->flags |= EP_Collate & pLeft->flags;
     }
     exprSetHeight(pRoot);
   }
@@ -76024,7 +74515,7 @@ static int dupedExprStructSize(Expr *p, int flags){
     assert( !ExprHasProperty(p, EP_FromJoin) ); 
     assert( (p->flags2 & EP2_MallocedToken)==0 );
     assert( (p->flags2 & EP2_Irreducible)==0 );
-    if( p->pLeft || p->pRight || p->pColl || p->x.pList ){
+    if( p->pLeft || p->pRight || p->x.pList ){
       nSize = EXPR_REDUCEDSIZE | EP_Reduced;
     }else{
       nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
@@ -76232,6 +74723,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){
     struct SrcList_item *pNewItem = &pNew->a[i];
     struct SrcList_item *pOldItem = &p->a[i];
     Table *pTab;
+    pNewItem->pSchema = pOldItem->pSchema;
     pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase);
     pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
     pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
@@ -76240,6 +74732,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){
     pNewItem->addrFillSub = pOldItem->addrFillSub;
     pNewItem->regReturn = pOldItem->regReturn;
     pNewItem->isCorrelated = pOldItem->isCorrelated;
+    pNewItem->viaCoroutine = pOldItem->viaCoroutine;
     pNewItem->zIndex = sqlite3DbStrDup(db, pOldItem->zIndex);
     pNewItem->notIndexed = pOldItem->notIndexed;
     pNewItem->pIndex = pOldItem->pIndex;
@@ -76722,12 +75215,16 @@ SQLITE_PRIVATE int sqlite3CodeOnce(Parse *pParse){
 
 /*
 ** This function is used by the implementation of the IN (...) operator.
-** It's job is to find or create a b-tree structure that may be used
-** either to test for membership of the (...) set or to iterate through
-** its members, skipping duplicates.
+** The pX parameter is the expression on the RHS of the IN operator, which
+** might be either a list of expressions or a subquery.
+**
+** The job of this routine is to find or create a b-tree object that can
+** be used either to test for membership in the RHS set or to iterate through
+** all members of the RHS set, skipping duplicates.
+**
+** A cursor is opened on the b-tree object that the RHS of the IN operator
+** and pX->iTable is set to the index of that cursor.
 **
-** The index of the cursor opened on the b-tree (database table, database index 
-** or ephermal table) is stored in pX->iTable before this function returns.
 ** The returned value of this function indicates the b-tree type, as follows:
 **
 **   IN_INDEX_ROWID - The cursor was opened on a database table.
@@ -76735,11 +75232,16 @@ SQLITE_PRIVATE int sqlite3CodeOnce(Parse *pParse){
 **   IN_INDEX_EPH -   The cursor was opened on a specially created and
 **                    populated epheremal table.
 **
-** An existing b-tree may only be used if the SELECT is of the simple
-** form:
+** An existing b-tree might be used if the RHS expression pX is a simple
+** subquery such as:
 **
 **     SELECT <column> FROM <table>
 **
+** If the RHS of the IN operator is a list or a more complex subquery, then
+** an ephemeral table might need to be generated from the RHS and then
+** pX->iTable made to point to the ephermeral table instead of an
+** existing table.  
+**
 ** If the prNotFound parameter is 0, then the b-tree will be used to iterate
 ** through the set members, skipping any duplicates. In this case an
 ** epheremal table must be used unless the selected <column> is guaranteed
@@ -76835,8 +75337,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
       ** comparison is the same as the affinity of the column. If
       ** it is not, it is not possible to use any index.
       */
-      char aff = comparisonAffinity(pX);
-      int affinity_ok = (pTab->aCol[iCol].affinity==aff||aff==SQLITE_AFF_NONE);
+      int affinity_ok = sqlite3IndexAffinityOk(pX, pTab->aCol[iCol].affinity);
 
       for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){
         if( (pIdx->aiColumn[0]==iCol)
@@ -76964,6 +75465,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
     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 */
 
@@ -76991,6 +75493,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
       if( rMayHaveNull==0 ) sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
       memset(&keyInfo, 0, sizeof(keyInfo));
       keyInfo.nField = 1;
+      keyInfo.aSortOrder = &sortOrder;
 
       if( ExprHasProperty(pExpr, EP_xIsSelect) ){
         /* Case 1:     expr IN (SELECT ...)
@@ -77003,7 +75506,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
 
         assert( !isRowid );
         sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
-        dest.affinity = (u8)affinity;
+        dest.affSdst = (u8)affinity;
         assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
         pExpr->x.pSelect->iLimit = 0;
         if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){
@@ -77031,6 +75534,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
           affinity = SQLITE_AFF_NONE;
         }
         keyInfo.aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
+        keyInfo.aSortOrder = &sortOrder;
 
         /* Loop through each expression in <exprlist>. */
         r1 = sqlite3GetTempReg(pParse);
@@ -77096,11 +75600,11 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
       sqlite3SelectDestInit(&dest, 0, ++pParse->nMem);
       if( pExpr->op==TK_SELECT ){
         dest.eDest = SRT_Mem;
-        sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iParm);
+        sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iSDParm);
         VdbeComment((v, "Init subquery result"));
       }else{
         dest.eDest = SRT_Exists;
-        sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iParm);
+        sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
         VdbeComment((v, "Init EXISTS result"));
       }
       sqlite3ExprDelete(pParse->db, pSel->pLimit);
@@ -77110,7 +75614,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
       if( sqlite3Select(pParse, pSel, &dest) ){
         return 0;
       }
-      rReg = dest.iParm;
+      rReg = dest.iSDParm;
       ExprSetIrreducible(pExpr);
       break;
     }
@@ -77357,7 +75861,7 @@ SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int
   ** for testing only - to verify that SQLite always gets the same answer
   ** with and without the column cache.
   */
-  if( pParse->db->flags & SQLITE_ColumnCache ) return;
+  if( OptimizationDisabled(pParse->db, SQLITE_ColumnCache) ) return;
 
   /* First replace any existing entry.
   **
@@ -77554,8 +76058,8 @@ SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse *pParse, int iStart, in
 SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
   int i;
   struct yColCache *p;
-  if( NEVER(iFrom==iTo) ) return;
-  sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg);
+  assert( iFrom>=iTo+nReg || iFrom+nReg<=iTo );
+  sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg-1);
   for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
     int x = p->iReg;
     if( x>=iFrom && x<iFrom+nReg ){
@@ -77564,18 +76068,6 @@ SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int n
   }
 }
 
-/*
-** Generate code to copy content from registers iFrom...iFrom+nReg-1
-** over to iTo..iTo+nReg-1.
-*/
-SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse *pParse, int iFrom, int iTo, int nReg){
-  int i;
-  if( NEVER(iFrom==iTo) ) return;
-  for(i=0; i<nReg; i++){
-    sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, iFrom+i, iTo+i);
-  }
-}
-
 #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
 /*
 ** Return true if any register in the range iFrom..iTo (inclusive)
@@ -78047,6 +76539,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
       sqlite3ReleaseTempReg(pParse, r4);
       break;
     }
+    case TK_COLLATE: 
     case TK_UPLUS: {
       inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
       break;
@@ -78416,6 +76909,12 @@ SQLITE_PRIVATE void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){
     case TK_ISNULL:  zUniOp = "ISNULL"; break;
     case TK_NOTNULL: zUniOp = "NOTNULL"; break;
 
+    case TK_COLLATE: {
+      sqlite3ExplainExpr(pOut, pExpr->pLeft);
+      sqlite3ExplainPrintf(pOut,".COLLATE(%s)",pExpr->u.zToken);
+      break;
+    }
+
     case TK_AGG_FUNCTION:
     case TK_CONST_FUNC:
     case TK_FUNCTION: {
@@ -78425,9 +76924,12 @@ SQLITE_PRIVATE void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){
       }else{
         pFarg = pExpr->x.pList;
       }
-      sqlite3ExplainPrintf(pOut, "%sFUNCTION:%s(",
-                           op==TK_AGG_FUNCTION ? "AGG_" : "",
-                           pExpr->u.zToken);
+      if( op==TK_AGG_FUNCTION ){
+        sqlite3ExplainPrintf(pOut, "AGG_FUNCTION%d:%s(",
+                             pExpr->op2, pExpr->u.zToken);
+      }else{
+        sqlite3ExplainPrintf(pOut, "FUNCTION:%s(", pExpr->u.zToken);
+      }
       if( pFarg ){
         sqlite3ExplainExprList(pOut, pFarg);
       }
@@ -78631,6 +77133,9 @@ static int evalConstExpr(Walker *pWalker, Expr *pExpr){
     case TK_REGISTER: {
       return WRC_Prune;
     }
+    case TK_COLLATE: {
+      return WRC_Continue;
+    }
     case TK_FUNCTION:
     case TK_AGG_FUNCTION:
     case TK_CONST_FUNC: {
@@ -78652,9 +77157,11 @@ static int evalConstExpr(Walker *pWalker, Expr *pExpr){
   }
   if( isAppropriateForFactoring(pExpr) ){
     int r1 = ++pParse->nMem;
-    int r2;
-    r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
-    if( NEVER(r1!=r2) ) sqlite3ReleaseTempReg(pParse, r1);
+    int r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
+    /* If r2!=r1, it means that register r1 is never used.  That is harmless
+    ** but suboptimal, so we want to know about the situation to fix it.
+    ** Hence the following assert: */
+    assert( r2==r1 );
     pExpr->op2 = pExpr->op;
     pExpr->op = TK_REGISTER;
     pExpr->iTable = r2;
@@ -78682,7 +77189,7 @@ static int evalConstExpr(Walker *pWalker, Expr *pExpr){
 SQLITE_PRIVATE void sqlite3ExprCodeConstants(Parse *pParse, Expr *pExpr){
   Walker w;
   if( pParse->cookieGoto ) return;
-  if( (pParse->db->flags & SQLITE_FactorOutConst)!=0 ) return;
+  if( OptimizationDisabled(pParse->db, SQLITE_FactorOutConst) ) return;
   w.xExprCallback = evalConstExpr;
   w.xSelectCallback = 0;
   w.pParse = pParse;
@@ -79071,7 +77578,15 @@ 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 ) return 2;
+  if( pA->op!=pB->op ){
+    if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB)<2 ){
+      return 1;
+    }
+    if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft)<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;
@@ -79083,11 +77598,9 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB){
   }else if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){
     if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
     if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
-      return 2;
+      return pA->op==TK_COLLATE ? 1 : 2;
     }
   }
-  if( (pA->flags & EP_ExpCollate)!=(pB->flags & EP_ExpCollate) ) return 1;
-  if( (pA->flags & EP_ExpCollate)!=0 && pA->pColl!=pB->pColl ) return 2;
   return 0;
 }
 
@@ -79118,38 +77631,60 @@ SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){
 }
 
 /*
-** This is the expression callback for sqlite3FunctionUsesOtherSrc().
-**
-** Determine if an expression references any table other than one of the
-** tables in pWalker->u.pSrcList and abort if it does.
+** An instance of the following structure is used by the tree walker
+** to count references to table columns in the arguments of an 
+** aggregate function, in order to implement the
+** sqlite3FunctionThisSrc() routine.
 */
-static int exprUsesOtherSrc(Walker *pWalker, Expr *pExpr){
-  if( pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN ){
+struct SrcCount {
+  SrcList *pSrc;   /* One particular FROM clause in a nested query */
+  int nThis;       /* Number of references to columns in pSrcList */
+  int nOther;      /* Number of references to columns in other FROM clauses */
+};
+
+/*
+** Count the number of references to columns.
+*/
+static int exprSrcCount(Walker *pWalker, Expr *pExpr){
+  /* The NEVER() on the second term is because sqlite3FunctionUsesThisSrc()
+  ** is always called before sqlite3ExprAnalyzeAggregates() and so the
+  ** TK_COLUMNs have not yet been converted into TK_AGG_COLUMN.  If
+  ** sqlite3FunctionUsesThisSrc() is used differently in the future, the
+  ** NEVER() will need to be removed. */
+  if( pExpr->op==TK_COLUMN || NEVER(pExpr->op==TK_AGG_COLUMN) ){
     int i;
-    SrcList *pSrc = pWalker->u.pSrcList;
+    struct SrcCount *p = pWalker->u.pSrcCount;
+    SrcList *pSrc = p->pSrc;
     for(i=0; i<pSrc->nSrc; i++){
-      if( pExpr->iTable==pSrc->a[i].iCursor ) return WRC_Continue;
+      if( pExpr->iTable==pSrc->a[i].iCursor ) break;
+    }
+    if( i<pSrc->nSrc ){
+      p->nThis++;
+    }else{
+      p->nOther++;
     }
-    return WRC_Abort;
-  }else{
-    return WRC_Continue;
   }
+  return WRC_Continue;
 }
 
 /*
-** Determine if any of the arguments to the pExpr Function references
-** any SrcList other than pSrcList.  Return true if they do.  Return
-** false if pExpr has no argument or has only constant arguments or
-** only references tables named in pSrcList.
+** Determine if any of the arguments to the pExpr Function reference
+** pSrcList.  Return true if they do.  Also return true if the function
+** has no arguments or has only constant arguments.  Return false if pExpr
+** references columns but not columns of tables found in pSrcList.
 */
-static int sqlite3FunctionUsesOtherSrc(Expr *pExpr, SrcList *pSrcList){
+SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){
   Walker w;
+  struct SrcCount cnt;
   assert( pExpr->op==TK_AGG_FUNCTION );
   memset(&w, 0, sizeof(w));
-  w.xExprCallback = exprUsesOtherSrc;
-  w.u.pSrcList = pSrcList;
-  if( sqlite3WalkExprList(&w, pExpr->x.pList)!=WRC_Continue ) return 1;
-  return 0;
+  w.xExprCallback = exprSrcCount;
+  w.u.pSrcCount = &cnt;
+  cnt.pSrc = pSrcList;
+  cnt.nThis = 0;
+  cnt.nOther = 0;
+  sqlite3WalkExprList(&w, pExpr->x.pList);
+  return cnt.nThis>0 || cnt.nOther==0;
 }
 
 /*
@@ -79268,7 +77803,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
     }
     case TK_AGG_FUNCTION: {
       if( (pNC->ncFlags & NC_InAggFunc)==0
-       && !sqlite3FunctionUsesOtherSrc(pExpr, pSrcList)
+       && pWalker->walkerDepth==pExpr->op2
       ){
         /* Check to see if pExpr is a duplicate of another aggregate 
         ** function that is already in the pAggInfo structure
@@ -79306,8 +77841,10 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
         ExprSetIrreducible(pExpr);
         pExpr->iAgg = (i16)i;
         pExpr->pAggInfo = pAggInfo;
+        return WRC_Prune;
+      }else{
+        return WRC_Continue;
       }
-      return WRC_Prune;
     }
   }
   return WRC_Continue;
@@ -79319,9 +77856,10 @@ static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){
 }
 
 /*
-** Analyze the given expression looking for aggregate functions and
-** for variables that need to be added to the pParse->aAgg[] array.
-** Make additional entries to the pParse->aAgg[] array as necessary.
+** Analyze the pExpr expression looking for aggregate functions and
+** for variables that need to be added to AggInfo object that pNC->pAggInfo
+** points to.  Additional entries are made on the AggInfo object as
+** necessary.
 **
 ** This routine should only be called after the expression has been
 ** analyzed by sqlite3ResolveExprNames().
@@ -79834,7 +78372,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
   assert( pSrc->nSrc==1 );
   assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
 
-  pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase);
+  pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
   if( !pTab ) goto exit_rename_table;
   iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
   zDb = db->aDb[iDb].zName;
@@ -80084,7 +78622,7 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
   ** If there is a NOT NULL constraint, then the default value for the
   ** column must not be NULL.
   */
-  if( pCol->isPrimKey ){
+  if( pCol->colFlags & COLFLAG_PRIMKEY ){
     sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");
     return;
   }
@@ -80177,7 +78715,7 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
   assert( pParse->pNewTable==0 );
   assert( sqlite3BtreeHoldsAllMutexes(db) );
   if( db->mallocFailed ) goto exit_begin_add_column;
-  pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase);
+  pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
   if( !pTab ) goto exit_begin_add_column;
 
 #ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -80424,7 +78962,7 @@ static void openStatTable(
           "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols
       );
       aRoot[i] = pParse->regRoot;
-      aCreateTbl[i] = 1;
+      aCreateTbl[i] = OPFLAG_P2ISREG;
     }else{
       /* The table already exists. If zWhere is not NULL, delete all entries 
       ** associated with the table zWhere. If zWhere is NULL, delete the
@@ -80504,12 +79042,11 @@ static void stat3Init(
   nRow = (tRowcnt)sqlite3_value_int64(argv[0]);
   mxSample = sqlite3_value_int(argv[1]);
   n = sizeof(*p) + sizeof(p->a[0])*mxSample;
-  p = sqlite3_malloc( n );
+  p = sqlite3MallocZero( n );
   if( p==0 ){
     sqlite3_result_error_nomem(context);
     return;
   }
-  memset(p, 0, n);
   p->a = (struct Stat3Sample*)&p[1];
   p->nRow = nRow;
   p->mxSample = mxSample;
@@ -81809,6 +80346,7 @@ SQLITE_PRIVATE int sqlite3FixInit(
   assert( db->nDb>iDb );
   pFix->pParse = pParse;
   pFix->zDb = db->aDb[iDb].zName;
+  pFix->pSchema = db->aDb[iDb].pSchema;
   pFix->zType = zType;
   pFix->pName = pName;
   return 1;
@@ -81839,14 +80377,15 @@ SQLITE_PRIVATE int sqlite3FixSrcList(
   if( NEVER(pList==0) ) return 0;
   zDb = pFix->zDb;
   for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
-    if( pItem->zDatabase==0 ){
-      pItem->zDatabase = sqlite3DbStrDup(pFix->pParse->db, zDb);
-    }else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){
+    if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){
       sqlite3ErrorMsg(pFix->pParse,
          "%s %T cannot reference objects in database %s",
          pFix->zType, pFix->pName, pItem->zDatabase);
       return 1;
     }
+    sqlite3DbFree(pFix->pParse->db, pItem->zDatabase);
+    pItem->zDatabase = 0;
+    pItem->pSchema = pFix->pSchema;
 #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
     if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
     if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;
@@ -82312,6 +80851,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
   sqlite3 *db;
   Vdbe *v;
 
+  assert( pParse->pToplevel==0 );
   db = pParse->db;
   if( db->mallocFailed ) return;
   if( pParse->nested ) return;
@@ -82504,6 +81044,31 @@ SQLITE_PRIVATE Table *sqlite3LocateTable(
   return p;
 }
 
+/*
+** Locate the table identified by *p.
+**
+** This is a wrapper around sqlite3LocateTable(). The difference between
+** sqlite3LocateTable() and this function is that this function restricts
+** the search to schema (p->pSchema) if it is not NULL. p->pSchema may be
+** non-NULL if it is part of a view or trigger program definition. See
+** sqlite3FixSrcList() for details.
+*/
+SQLITE_PRIVATE Table *sqlite3LocateTableItem(
+  Parse *pParse, 
+  int isView, 
+  struct SrcList_item *p
+){
+  const char *zDb;
+  assert( p->pSchema==0 || p->zDatabase==0 );
+  if( p->pSchema ){
+    int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema);
+    zDb = pParse->db->aDb[iDb].zName;
+  }else{
+    zDb = p->zDatabase;
+  }
+  return sqlite3LocateTable(pParse, isView, p->zName, zDb);
+}
+
 /*
 ** Locate the in-memory structure that describes 
 ** a particular index given the name of that index
@@ -82719,7 +81284,7 @@ SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
     if( !db || db->pnBytesFreed==0 ){
       char *zName = pIndex->zName; 
       TESTONLY ( Index *pOld = ) sqlite3HashInsert(
-         &pIndex->pSchema->idxHash, zName, sqlite3Strlen30(zName), 0
+         &pIndex->pSchema->idxHash, zName, sqlite3Strlen30(zName), 0
       );
       assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
       assert( pOld==pIndex || pOld==0 );
@@ -83354,7 +81919,7 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey(
   pTab->tabFlags |= TF_HasPrimaryKey;
   if( pList==0 ){
     iCol = pTab->nCol - 1;
-    pTab->aCol[iCol].isPrimKey = 1;
+    pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
   }else{
     for(i=0; i<pList->nExpr; i++){
       for(iCol=0; iCol<pTab->nCol; iCol++){
@@ -83363,7 +81928,7 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey(
         }
       }
       if( iCol<pTab->nCol ){
-        pTab->aCol[iCol].isPrimKey = 1;
+        pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
       }
     }
     if( pList->nExpr>1 ) iCol = -1;
@@ -83480,10 +82045,7 @@ SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){
 
   pColl = sqlite3FindCollSeq(db, enc, zName, initbusy);
   if( !initbusy && (!pColl || !pColl->xCmp) ){
-    pColl = sqlite3GetCollSeq(db, enc, pColl, zName);
-    if( !pColl ){
-      sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
-    }
+    pColl = sqlite3GetCollSeq(pParse, enc, pColl, zName);
   }
 
   return pColl;
@@ -83766,7 +82328,7 @@ SQLITE_PRIVATE void sqlite3EndTable(
 
       assert(pParse->nTab==1);
       sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb);
-      sqlite3VdbeChangeP5(v, 1);
+      sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG);
       pParse->nTab = 2;
       sqlite3SelectDestInit(&dest, SRT_Table, 1);
       sqlite3Select(pParse, pSelect, &dest);
@@ -84182,6 +82744,7 @@ static void destroyTable(Parse *pParse, Table *pTab){
       return;
     }else{
       int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
+      assert( iDb>=0 && iDb<pParse->db->nDb );
       destroyRootPage(pParse, iLargest, iDb);
       iDestroyed = iLargest;
     }
@@ -84299,8 +82862,7 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView,
   assert( pParse->nErr==0 );
   assert( pName->nSrc==1 );
   if( noErr ) db->suppressErr++;
-  pTab = sqlite3LocateTable(pParse, isView, 
-                            pName->a[0].zName, pName->a[0].zDatabase);
+  pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
   if( noErr ) db->suppressErr--;
 
   if( pTab==0 ){
@@ -84582,9 +83144,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
   pKey = sqlite3IndexKeyinfo(pParse, pIndex);
   sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, 
                     (char *)pKey, P4_KEYINFO_HANDOFF);
-  if( memRootPage>=0 ){
-    sqlite3VdbeChangeP5(v, 1);
-  }
+  sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));
 
 #ifndef SQLITE_OMIT_MERGE_SORT
   /* Open the sorter cursor if we are to use one. */
@@ -84723,7 +83283,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
     assert( pName && pName->z );
 
 #ifndef SQLITE_OMIT_TEMPDB
-    /* If the index name was unqualified, check if the the table
+    /* If the index name was unqualified, check if the table
     ** is a temp table. If so, set the database to 1. Do not do this
     ** if initialising a database schema.
     */
@@ -84742,9 +83302,9 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
       ** sqlite3FixSrcList can never fail. */
       assert(0);
     }
-    pTab = sqlite3LocateTable(pParse, 0, pTblName->a[0].zName, 
-        pTblName->a[0].zDatabase);
-    if( !pTab || db->mallocFailed ) goto exit_create_index;
+    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 );
   }else{
     assert( pName==0 );
@@ -84855,10 +83415,8 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
   for(i=0; i<pList->nExpr; i++){
     Expr *pExpr = pList->a[i].pExpr;
     if( pExpr ){
-      CollSeq *pColl = pExpr->pColl;
-      /* Either pColl!=0 or there was an OOM failure.  But if an OOM
-      ** failure we have quit before reaching this point. */
-      if( ALWAYS(pColl) ){
+      CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr);
+      if( pColl ){
         nExtra += (1 + sqlite3Strlen30(pColl->zName));
       }
     }
@@ -84921,6 +83479,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
     const char *zColName = pListItem->zName;
     Column *pTabCol;
     int requestedSortOrder;
+    CollSeq *pColl;                /* Collating sequence */
     char *zColl;                   /* Collation sequence name */
 
     for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){
@@ -84933,14 +83492,11 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
       goto exit_create_index;
     }
     pIndex->aiColumn[i] = j;
-    /* Justification of the ALWAYS(pListItem->pExpr->pColl):  Because of
-    ** the way the "idxlist" non-terminal is constructed by the parser,
-    ** if pListItem->pExpr is not null then either pListItem->pExpr->pColl
-    ** must exist or else there must have been an OOM error.  But if there
-    ** was an OOM error, we would never reach this point. */
-    if( pListItem->pExpr && ALWAYS(pListItem->pExpr->pColl) ){
+    if( pListItem->pExpr
+     && (pColl = sqlite3ExprCollSeq(pParse, pListItem->pExpr))!=0
+    ){
       int nColl;
-      zColl = pListItem->pExpr->pColl->zName;
+      zColl = pColl->zName;
       nColl = sqlite3Strlen30(zColl) + 1;
       assert( nExtra>=nColl );
       memcpy(zExtra, zColl, nColl);
@@ -85754,6 +84310,15 @@ SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *pParse){
 SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
   Parse *pToplevel = sqlite3ParseToplevel(pParse);
 
+#ifndef SQLITE_OMIT_TRIGGER
+  if( pToplevel!=pParse ){
+    /* This branch is taken if a trigger is currently being coded. In this
+    ** case, set cookieGoto to a non-zero value to show that this function
+    ** has been called. This is used by the sqlite3ExprCodeConstants()
+    ** function. */
+    pParse->cookieGoto = -1;
+  }
+#endif
   if( pToplevel->cookieGoto==0 ){
     Vdbe *v = sqlite3GetVdbe(pToplevel);
     if( v==0 ) return;  /* This only happens if there was a prior error */
@@ -86103,17 +84668,18 @@ static int synthCollSeq(sqlite3 *db, CollSeq *pColl){
 **
 ** The return value is either the collation sequence to be used in database
 ** db for collation type name zName, length nName, or NULL, if no collation
-** sequence can be found.
+** sequence can be found.  If no collation is found, leave an error message.
 **
 ** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq()
 */
 SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(
-  sqlite3* db,          /* The database connection */
+  Parse *pParse,        /* Parsing context */
   u8 enc,               /* The desired encoding for the collating sequence */
   CollSeq *pColl,       /* Collating sequence with native encoding, or NULL */
   const char *zName     /* Collating sequence name */
 ){
   CollSeq *p;
+  sqlite3 *db = pParse->db;
 
   p = pColl;
   if( !p ){
@@ -86130,6 +84696,9 @@ SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(
     p = 0;
   }
   assert( !p || p->xCmp );
+  if( p==0 ){
+    sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
+  }
   return p;
 }
 
@@ -86148,10 +84717,8 @@ SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
   if( pColl ){
     const char *zName = pColl->zName;
     sqlite3 *db = pParse->db;
-    CollSeq *p = sqlite3GetCollSeq(db, ENC(db), pColl, zName);
+    CollSeq *p = sqlite3GetCollSeq(pParse, ENC(db), pColl, zName);
     if( !p ){
-      sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
-      pParse->nErr++;
       return SQLITE_ERROR;
     }
     assert( p==pColl );
@@ -86538,7 +85105,7 @@ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
   struct SrcList_item *pItem = pSrc->a;
   Table *pTab;
   assert( pItem && pSrc->nSrc==1 );
-  pTab = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase);
+  pTab = sqlite3LocateTableItem(pParse, 0, pItem);
   sqlite3DeleteTable(pParse->db, pItem->pTab);
   pItem->pTab = pTab;
   if( pTab ){
@@ -86618,6 +85185,7 @@ SQLITE_PRIVATE void sqlite3MaterializeView(
       sqlite3SelectDelete(db, pDup);
     }
     pDup = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0);
+    if( pDup ) pDup->selFlags |= SF_Materialize;
   }
   sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
   sqlite3Select(pParse, pDup, &dest);
@@ -86877,7 +85445,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
     */
     sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet);
     pWInfo = sqlite3WhereBegin(
-        pParse, pTabList, pWhere, 0, 0, WHERE_DUPLICATES_OK
+        pParse, pTabList, pWhere, 0, 0, WHERE_DUPLICATES_OK, 0
     );
     if( pWInfo==0 ) goto delete_from_cleanup;
     regRowid = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, iRowid, 0);
@@ -87144,7 +85712,9 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey(
   }
   if( doMakeRec ){
     const char *zAff;
-    if( pTab->pSelect || (pParse->db->flags & SQLITE_IdxRealAsInt)!=0 ){
+    if( pTab->pSelect
+     || OptimizationDisabled(pParse->db, SQLITE_IdxRealAsInt)
+    ){
       zAff = 0;
     }else{
       zAff = sqlite3IndexAffinityStr(v, pIdx);
@@ -87326,6 +85896,56 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
   }
 }
 
+/*
+** Implementation of the instr() function.
+**
+** instr(haystack,needle) finds the first occurrence of needle
+** in haystack and returns the number of previous characters plus 1,
+** or 0 if needle does not occur within haystack.
+**
+** If both haystack and needle are BLOBs, then the result is one more than
+** the number of bytes in haystack prior to the first occurrence of needle,
+** or 0 if needle never occurs in haystack.
+*/
+static void instrFunc(
+  sqlite3_context *context,
+  int argc,
+  sqlite3_value **argv
+){
+  const unsigned char *zHaystack;
+  const unsigned char *zNeedle;
+  int nHaystack;
+  int nNeedle;
+  int typeHaystack, typeNeedle;
+  int N = 1;
+  int isText;
+
+  UNUSED_PARAMETER(argc);
+  typeHaystack = sqlite3_value_type(argv[0]);
+  typeNeedle = sqlite3_value_type(argv[1]);
+  if( typeHaystack==SQLITE_NULL || typeNeedle==SQLITE_NULL ) return;
+  nHaystack = sqlite3_value_bytes(argv[0]);
+  nNeedle = sqlite3_value_bytes(argv[1]);
+  if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){
+    zHaystack = sqlite3_value_blob(argv[0]);
+    zNeedle = sqlite3_value_blob(argv[1]);
+    isText = 0;
+  }else{
+    zHaystack = sqlite3_value_text(argv[0]);
+    zNeedle = sqlite3_value_text(argv[1]);
+    isText = 1;
+  }
+  while( nNeedle<=nHaystack && memcmp(zHaystack, zNeedle, nNeedle)!=0 ){
+    N++;
+    do{
+      nHaystack--;
+      zHaystack++;
+    }while( isText && (zHaystack[0]&0xc0)==0x80 );
+  }
+  if( nNeedle>nHaystack ) N = 0;
+  sqlite3_result_int(context, N);
+}
+
 /*
 ** Implementation of the substr() function.
 **
@@ -87525,33 +86145,14 @@ static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
   }
 }
 
-
-#if 0  /* This function is never used. */
-/*
-** The COALESCE() and IFNULL() functions used to be implemented as shown
-** here.  But now they are implemented as VDBE code so that unused arguments
-** do not have to be computed.  This legacy implementation is retained as
-** comment.
-*/
 /*
-** Implementation of the IFNULL(), NVL(), and COALESCE() functions.  
-** All three do the same thing.  They return the first non-NULL
-** argument.
+** The COALESCE() and IFNULL() functions are implemented as VDBE code so
+** that unused argument values do not have to be computed.  However, we
+** still need some kind of function implementation for this routines in
+** the function table.  That function implementation will never be called
+** so it doesn't matter what the implementation is.  We might as well use
+** the "version()" function as a substitute.
 */
-static void ifnullFunc(
-  sqlite3_context *context,
-  int argc,
-  sqlite3_value **argv
-){
-  int i;
-  for(i=0; i<argc; i++){
-    if( SQLITE_NULL!=sqlite3_value_type(argv[i]) ){
-      sqlite3_result_value(context, argv[i]);
-      break;
-    }
-  }
-}
-#endif /* NOT USED */
 #define ifnullFunc versionFunc   /* Substitute function - never called */
 
 /*
@@ -87670,7 +86271,7 @@ struct compareInfo {
 ** whereas only characters less than 0x80 do in ASCII.
 */
 #if defined(SQLITE_EBCDIC)
-# define sqlite3Utf8Read(A,C)  (*(A++))
+# define sqlite3Utf8Read(A)    (*((*A)++))
 # define GlogUpperToLower(A)   A = sqlite3UpperToLower[A]
 #else
 # define GlogUpperToLower(A)   if( !((A)&~0x7f) ){ A = sqlite3UpperToLower[A]; }
@@ -87727,18 +86328,18 @@ static int patternCompare(
   u8 noCase = pInfo->noCase; 
   int prevEscape = 0;     /* True if the previous character was 'escape' */
 
-  while( (c = sqlite3Utf8Read(zPattern,&zPattern))!=0 ){
-    if( !prevEscape && c==matchAll ){
-      while( (c=sqlite3Utf8Read(zPattern,&zPattern)) == matchAll
+  while( (c = sqlite3Utf8Read(&zPattern))!=0 ){
+    if( c==matchAll && !prevEscape ){
+      while( (c=sqlite3Utf8Read(&zPattern)) == matchAll
                || c == matchOne ){
-        if( c==matchOne && sqlite3Utf8Read(zString, &zString)==0 ){
+        if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){
           return 0;
         }
       }
       if( c==0 ){
         return 1;
       }else if( c==esc ){
-        c = sqlite3Utf8Read(zPattern, &zPattern);
+        c = sqlite3Utf8Read(&zPattern);
         if( c==0 ){
           return 0;
         }
@@ -87750,25 +86351,25 @@ static int patternCompare(
         }
         return *zString!=0;
       }
-      while( (c2 = sqlite3Utf8Read(zString,&zString))!=0 ){
+      while( (c2 = sqlite3Utf8Read(&zString))!=0 ){
         if( noCase ){
           GlogUpperToLower(c2);
           GlogUpperToLower(c);
           while( c2 != 0 && c2 != c ){
-            c2 = sqlite3Utf8Read(zString, &zString);
+            c2 = sqlite3Utf8Read(&zString);
             GlogUpperToLower(c2);
           }
         }else{
           while( c2 != 0 && c2 != c ){
-            c2 = sqlite3Utf8Read(zString, &zString);
+            c2 = sqlite3Utf8Read(&zString);
           }
         }
         if( c2==0 ) return 0;
         if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
       }
       return 0;
-    }else if( !prevEscape && c==matchOne ){
-      if( sqlite3Utf8Read(zString, &zString)==0 ){
+    }else if( c==matchOne && !prevEscape ){
+      if( sqlite3Utf8Read(&zString)==0 ){
         return 0;
       }
     }else if( c==matchSet ){
@@ -87776,20 +86377,20 @@ static int patternCompare(
       assert( esc==0 );    /* This only occurs for GLOB, not LIKE */
       seen = 0;
       invert = 0;
-      c = sqlite3Utf8Read(zString, &zString);
+      c = sqlite3Utf8Read(&zString);
       if( c==0 ) return 0;
-      c2 = sqlite3Utf8Read(zPattern, &zPattern);
+      c2 = sqlite3Utf8Read(&zPattern);
       if( c2=='^' ){
         invert = 1;
-        c2 = sqlite3Utf8Read(zPattern, &zPattern);
+        c2 = sqlite3Utf8Read(&zPattern);
       }
       if( c2==']' ){
         if( c==']' ) seen = 1;
-        c2 = sqlite3Utf8Read(zPattern, &zPattern);
+        c2 = sqlite3Utf8Read(&zPattern);
       }
       while( c2 && c2!=']' ){
         if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){
-          c2 = sqlite3Utf8Read(zPattern, &zPattern);
+          c2 = sqlite3Utf8Read(&zPattern);
           if( c>=prior_c && c<=c2 ) seen = 1;
           prior_c = 0;
         }else{
@@ -87798,7 +86399,7 @@ static int patternCompare(
           }
           prior_c = c2;
         }
-        c2 = sqlite3Utf8Read(zPattern, &zPattern);
+        c2 = sqlite3Utf8Read(&zPattern);
       }
       if( c2==0 || (seen ^ invert)==0 ){
         return 0;
@@ -87806,7 +86407,7 @@ static int patternCompare(
     }else if( esc==c && !prevEscape ){
       prevEscape = 1;
     }else{
-      c2 = sqlite3Utf8Read(zString, &zString);
+      c2 = sqlite3Utf8Read(&zString);
       if( noCase ){
         GlogUpperToLower(c);
         GlogUpperToLower(c2);
@@ -87878,7 +86479,7 @@ static void likeFunc(
           "ESCAPE expression must be a single character", -1);
       return;
     }
-    escape = sqlite3Utf8Read(zEsc, &zEsc);
+    escape = sqlite3Utf8Read(&zEsc);
   }
   if( zA && zB ){
     struct compareInfo *pInfo = sqlite3_user_data(context);
@@ -88021,8 +86622,19 @@ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
   assert( argc==1 );
   UNUSED_PARAMETER(argc);
   switch( sqlite3_value_type(argv[0]) ){
-    case SQLITE_INTEGER:
     case SQLITE_FLOAT: {
+      double r1, r2;
+      char zBuf[50];
+      r1 = sqlite3_value_double(argv[0]);
+      sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.15g", r1);
+      sqlite3AtoF(zBuf, &r2, 20, SQLITE_UTF8);
+      if( r1!=r2 ){
+        sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.20e", r1);
+      }
+      sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
+      break;
+    }
+    case SQLITE_INTEGER: {
       sqlite3_result_value(context, argv[0]);
       break;
     }
@@ -88702,6 +87314,7 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
     AGGREGATE(max,               1, 1, 1, minmaxStep,      minMaxFinalize ),
     FUNCTION2(typeof,            1, 0, 0, typeofFunc,  SQLITE_FUNC_TYPEOF),
     FUNCTION2(length,            1, 0, 0, lengthFunc,  SQLITE_FUNC_LENGTH),
+    FUNCTION(instr,              2, 0, 0, instrFunc        ),
     FUNCTION(substr,             2, 0, 0, substrFunc       ),
     FUNCTION(substr,             3, 0, 0, substrFunc       ),
     FUNCTION(abs,                1, 0, 0, absFunc          ),
@@ -89285,12 +87898,15 @@ static void fkScanChildren(
       ** expression to the parent key column defaults.  */
       if( pIdx ){
         Column *pCol;
+        const char *zColl;
         iCol = pIdx->aiColumn[i];
         pCol = &pTab->aCol[iCol];
         if( pTab->iPKey==iCol ) iCol = -1;
         pLeft->iTable = regData+iCol+1;
         pLeft->affinity = pCol->affinity;
-        pLeft->pColl = sqlite3LocateCollSeq(pParse, pCol->zColl);
+        zColl = pCol->zColl;
+        if( zColl==0 ) zColl = db->pDfltColl->zName;
+        pLeft = sqlite3ExprAddCollateString(pParse, pLeft, zColl);
       }else{
         pLeft->iTable = regData;
         pLeft->affinity = SQLITE_AFF_INTEGER;
@@ -89334,7 +87950,7 @@ static void fkScanChildren(
   ** clause. If the constraint is not deferred, throw an exception for
   ** each row found. Otherwise, for deferred constraints, increment the
   ** deferred constraint counter by nIncr for each row selected.  */
-  pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0);
+  pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0);
   if( nIncr>0 && pFKey->isDeferred==0 ){
     sqlite3ParseToplevel(pParse)->mayAbort = 1;
   }
@@ -89699,7 +88315,8 @@ SQLITE_PRIVATE int sqlite3FkRequired(
           int iKey;
           for(iKey=0; iKey<pTab->nCol; iKey++){
             Column *pCol = &pTab->aCol[iKey];
-            if( (zKey ? !sqlite3StrICmp(pCol->zName, zKey) : pCol->isPrimKey) ){
+            if( (zKey ? !sqlite3StrICmp(pCol->zName, zKey)
+                      : (pCol->colFlags & COLFLAG_PRIMKEY)!=0) ){
               if( aChange[iKey]>=0 ) return 1;
               if( iKey==pTab->iPKey && chngRowid ) return 1;
             }
@@ -90020,7 +88637,7 @@ SQLITE_PRIVATE void sqlite3OpenTable(
   int opcode      /* OP_OpenRead or OP_OpenWrite */
 ){
   Vdbe *v;
-  if( IsVirtual(pTab) ) return;
+  assert( !IsVirtual(pTab) );
   v = sqlite3GetVdbe(p);
   assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
   sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite)?1:0, pTab->zName);
@@ -90315,6 +88932,97 @@ SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){
 #endif /* SQLITE_OMIT_AUTOINCREMENT */
 
 
+/*
+** Generate code for a co-routine that will evaluate a subquery one
+** row at a time.
+**
+** The pSelect parameter is the subquery that the co-routine will evaluation.
+** Information about the location of co-routine and the registers it will use
+** is returned by filling in the pDest object.
+**
+** Registers are allocated as follows:
+**
+**   pDest->iSDParm      The register holding the next entry-point of the
+**                       co-routine.  Run the co-routine to its next breakpoint
+**                       by calling "OP_Yield $X" where $X is pDest->iSDParm.
+**
+**   pDest->iSDParm+1    The register holding the "completed" flag for the
+**                       co-routine. This register is 0 if the previous Yield
+**                       generated a new result row, or 1 if the subquery
+**                       has completed.  If the Yield is called again
+**                       after this register becomes 1, then the VDBE will
+**                       halt with an SQLITE_INTERNAL error.
+**
+**   pDest->iSdst        First result register.
+**
+**   pDest->nSdst        Number of result registers.
+**
+** This routine handles all of the register allocation and fills in the
+** pDest structure appropriately.
+**
+** Here is a schematic of the generated code assuming that X is the 
+** co-routine entry-point register reg[pDest->iSDParm], that EOF is the
+** completed flag reg[pDest->iSDParm+1], and R and S are the range of
+** registers that hold the result set, reg[pDest->iSdst] through
+** reg[pDest->iSdst+pDest->nSdst-1]:
+**
+**         X <- A
+**         EOF <- 0
+**         goto B
+**      A: setup for the SELECT
+**         loop rows in the SELECT
+**           load results into registers R..S
+**           yield X
+**         end loop
+**         cleanup after the SELECT
+**         EOF <- 1
+**         yield X
+**         halt-error
+**      B:
+**
+** To use this subroutine, the caller generates code as follows:
+**
+**         [ Co-routine generated by this subroutine, shown above ]
+**      S: yield X
+**         if EOF goto E
+**         if skip this row, goto C
+**         if terminate loop, goto E
+**         deal with this row
+**      C: goto S
+**      E:
+*/
+SQLITE_PRIVATE int sqlite3CodeCoroutine(Parse *pParse, Select *pSelect, SelectDest *pDest){
+  int regYield;       /* Register holding co-routine entry-point */
+  int regEof;         /* Register holding co-routine completion flag */
+  int addrTop;        /* Top of the co-routine */
+  int j1;             /* Jump instruction */
+  int rc;             /* Result code */
+  Vdbe *v;            /* VDBE under construction */
+
+  regYield = ++pParse->nMem;
+  regEof = ++pParse->nMem;
+  v = sqlite3GetVdbe(pParse);
+  addrTop = sqlite3VdbeCurrentAddr(v);
+  sqlite3VdbeAddOp2(v, OP_Integer, addrTop+2, regYield); /* X <- A */
+  VdbeComment((v, "Co-routine entry point"));
+  sqlite3VdbeAddOp2(v, OP_Integer, 0, regEof);           /* EOF <- 0 */
+  VdbeComment((v, "Co-routine completion flag"));
+  sqlite3SelectDestInit(pDest, SRT_Coroutine, regYield);
+  j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
+  rc = sqlite3Select(pParse, pSelect, pDest);
+  assert( pParse->nErr==0 || rc );
+  if( pParse->db->mallocFailed && rc==SQLITE_OK ) rc = SQLITE_NOMEM;
+  if( rc ) return rc;
+  sqlite3VdbeAddOp2(v, OP_Integer, 1, regEof);            /* EOF <- 1 */
+  sqlite3VdbeAddOp1(v, OP_Yield, regYield);   /* yield X */
+  sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort);
+  VdbeComment((v, "End of coroutine"));
+  sqlite3VdbeJumpHere(v, j1);                             /* label B: */
+  return rc;
+}
+
+
+
 /* Forward declaration */
 static int xferOptimization(
   Parse *pParse,        /* Parser context */
@@ -90563,55 +89271,16 @@ SQLITE_PRIVATE void sqlite3Insert(
   ** co-routine is the common header to the 3rd and 4th templates.
   */
   if( pSelect ){
-    /* Data is coming from a SELECT.  Generate code to implement that SELECT
-    ** as a co-routine.  The code is common to both the 3rd and 4th
-    ** templates:
-    **
-    **         EOF <- 0
-    **         X <- A
-    **         goto B
-    **      A: setup for the SELECT
-    **         loop over the tables in the SELECT
-    **           load value into register R..R+n
-    **           yield X
-    **         end loop
-    **         cleanup after the SELECT
-    **         EOF <- 1
-    **         yield X
-    **         halt-error
-    **
-    ** On each invocation of the co-routine, it puts a single row of the
-    ** SELECT result into registers dest.iMem...dest.iMem+dest.nMem-1.
-    ** (These output registers are allocated by sqlite3Select().)  When
-    ** the SELECT completes, it sets the EOF flag stored in regEof.
-    */
-    int rc, j1;
-
-    regEof = ++pParse->nMem;
-    sqlite3VdbeAddOp2(v, OP_Integer, 0, regEof);      /* EOF <- 0 */
-    VdbeComment((v, "SELECT eof flag"));
-    sqlite3SelectDestInit(&dest, SRT_Coroutine, ++pParse->nMem);
-    addrSelect = sqlite3VdbeCurrentAddr(v)+2;
-    sqlite3VdbeAddOp2(v, OP_Integer, addrSelect-1, dest.iParm);
-    j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
-    VdbeComment((v, "Jump over SELECT coroutine"));
-
-    /* Resolve the expressions in the SELECT statement and execute it. */
-    rc = sqlite3Select(pParse, pSelect, &dest);
-    assert( pParse->nErr==0 || rc );
-    if( rc || NEVER(pParse->nErr) || db->mallocFailed ){
-      goto insert_cleanup;
-    }
-    sqlite3VdbeAddOp2(v, OP_Integer, 1, regEof);         /* EOF <- 1 */
-    sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm);   /* yield X */
-    sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort);
-    VdbeComment((v, "End of SELECT coroutine"));
-    sqlite3VdbeJumpHere(v, j1);                          /* label B: */
+    /* Data is coming from a SELECT.  Generate a co-routine to run that
+    ** SELECT. */
+    int rc = sqlite3CodeCoroutine(pParse, pSelect, &dest);
+    if( rc ) goto insert_cleanup;
 
-    regFromSelect = dest.iMem;
+    regEof = dest.iSDParm + 1;
+    regFromSelect = dest.iSdst;
     assert( pSelect->pEList );
     nColumn = pSelect->pEList->nExpr;
-    assert( dest.nMem==nColumn );
+    assert( dest.nSdst==nColumn );
 
     /* Set useTempTable to TRUE if the result of the SELECT statement
     ** should be written into a temporary table (template 4).  Set to
@@ -90647,7 +89316,7 @@ SQLITE_PRIVATE void sqlite3Insert(
       regRec = sqlite3GetTempReg(pParse);
       regTempRowid = sqlite3GetTempReg(pParse);
       sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn);
-      addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm);
+      addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
       addrIf = sqlite3VdbeAddOp1(v, OP_If, regEof);
       sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec);
       sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid);
@@ -90784,7 +89453,7 @@ SQLITE_PRIVATE void sqlite3Insert(
     **         goto C
     **      D: ...
     */
-    addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm);
+    addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
     addrInsTop = sqlite3VdbeAddOp1(v, OP_If, regEof);
   }
 
@@ -91266,7 +89935,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
       case OE_Replace: {
         /* If there are DELETE triggers on this table and the
         ** recursive-triggers flag is set, call GenerateRowDelete() to
-        ** remove the conflicting row from the the table. This will fire
+        ** remove the conflicting row from the table. This will fire
         ** the triggers and remove both the table and index b-tree entries.
         **
         ** Otherwise, if there are no triggers or the recursive-triggers
@@ -91686,7 +90355,7 @@ static int xferOptimization(
   ** we have to check the semantics.
   */
   pItem = pSelect->pSrc->a;
-  pSrc = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase);
+  pSrc = sqlite3LocateTableItem(pParse, 0, pItem);
   if( pSrc==0 ){
     return 0;   /* FROM clause does not contain a real table */
   }
@@ -93464,6 +92133,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
   aFcntl[1] = zLeft;
   aFcntl[2] = zRight;
   aFcntl[3] = 0;
+  db->busyHandler.nBusy = 0;
   rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
   if( rc==SQLITE_OK ){
     if( aFcntl[0] ){
@@ -94081,7 +92751,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
         }else{
           sqlite3VdbeAddOp2(v, OP_Null, 0, 5);
         }
-        sqlite3VdbeAddOp2(v, OP_Integer, pCol->isPrimKey, 6);
+        sqlite3VdbeAddOp2(v, OP_Integer,
+                            (pCol->colFlags&COLFLAG_PRIMKEY)!=0, 6);
         sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
       }
     }
@@ -94267,6 +92938,19 @@ SQLITE_PRIVATE void sqlite3Pragma(
 
     int isQuick = (sqlite3Tolower(zLeft[0])=='q');
 
+    /* If the PRAGMA command was of the form "PRAGMA <db>.integrity_check",
+    ** then iDb is set to the index of the database identified by <db>.
+    ** In this case, the integrity of database iDb only is verified by
+    ** the VDBE created below.
+    **
+    ** Otherwise, if the command was simply "PRAGMA integrity_check" (or
+    ** "PRAGMA quick_check"), then iDb is set to 0. In this case, set iDb
+    ** to -1 here, to indicate that the VDBE should verify the integrity
+    ** of all attached databases.  */
+    assert( iDb>=0 );
+    assert( iDb==0 || pId2->z );
+    if( pId2->z==0 ) iDb = -1;
+
     /* Initialize the VDBE program */
     if( sqlite3ReadSchema(pParse) ) goto pragma_out;
     pParse->nMem = 6;
@@ -94290,6 +92974,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
       int cnt = 0;
 
       if( OMIT_TEMPDB && i==1 ) continue;
+      if( iDb>=0 && i!=iDb ) continue;
 
       sqlite3CodeVerifySchema(pParse, i);
       addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */
@@ -94301,7 +92986,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
       ** Begin by filling registers 2, 3, ... with the root pages numbers
       ** for all tables and indices in the database.
       */
-      assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+      assert( sqlite3SchemaMutexHeld(db, i, 0) );
       pTbls = &db->aDb[i].pSchema->tblHash;
       for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
         Table *pTab = sqliteHashData(x);
@@ -94326,7 +93011,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
       sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
          sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName),
          P4_DYNAMIC);
-      sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1);
+      sqlite3VdbeAddOp2(v, OP_Move, 2, 4);
       sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2);
       sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1);
       sqlite3VdbeJumpHere(v, addr);
@@ -94629,6 +93314,22 @@ SQLITE_PRIVATE void sqlite3Pragma(
     sqlite3_db_release_memory(db);
   }else
 
+  /*
+  **   PRAGMA busy_timeout
+  **   PRAGMA busy_timeout = N
+  **
+  ** Call sqlite3_busy_timeout(db, N).  Return the current timeout value
+  ** if one is set.  If no busy handler or a different busy handler is set
+  ** then 0 is returned.  Setting the busy_timeout to 0 or negative
+  ** disables the timeout.
+  */
+  if( sqlite3StrICmp(zLeft, "busy_timeout")==0 ){
+    if( zRight ){
+      sqlite3_busy_timeout(db, sqlite3Atoi(zRight));
+    }
+    returnSingleInt(pParse, "timeout",  db->busyTimeout);
+  }else
+
 #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
   /*
   ** Report the current state of file logs for all databases
@@ -94644,13 +93345,12 @@ SQLITE_PRIVATE void sqlite3Pragma(
     sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "status", SQLITE_STATIC);
     for(i=0; i<db->nDb; i++){
       Btree *pBt;
-      Pager *pPager;
       const char *zState = "unknown";
       int j;
       if( db->aDb[i].zName==0 ) continue;
       sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, db->aDb[i].zName, P4_STATIC);
       pBt = db->aDb[i].pBt;
-      if( pBt==0 || (pPager = sqlite3BtreePager(pBt))==0 ){
+      if( pBt==0 || sqlite3BtreePager(pBt)==0 ){
         zState = "closed";
       }else if( sqlite3_file_control(db, i ? db->aDb[i].zName : 0, 
                                      SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){
@@ -94859,7 +93559,9 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char
 static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
   int rc;
   int i;
+#ifndef SQLITE_OMIT_DEPRECATED
   int size;
+#endif
   Table *pTab;
   Db *pDb;
   char const *azArg[4];
@@ -95625,10 +94327,10 @@ static void clearSelect(sqlite3 *db, Select *p){
 */
 SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){
   pDest->eDest = (u8)eDest;
-  pDest->iParm = iParm;
-  pDest->affinity = 0;
-  pDest->iMem = 0;
-  pDest->nMem = 0;
+  pDest->iSDParm = iParm;
+  pDest->affSdst = 0;
+  pDest->iSdst = 0;
+  pDest->nSdst = 0;
 }
 
 
@@ -96114,6 +94816,19 @@ static int checkForMultiColumnSelectError(
 }
 #endif
 
+/*
+** An instance of the following object is used to record information about
+** how to process the DISTINCT keyword, to simplify passing that information
+** into the selectInnerLoop() routine.
+*/
+typedef struct DistinctCtx DistinctCtx;
+struct DistinctCtx {
+  u8 isTnct;      /* True if the DISTINCT keyword is present */
+  u8 eTnctType;   /* One of the WHERE_DISTINCT_* operators */
+  int tabTnct;    /* Ephemeral table used for DISTINCT processing */
+  int addrTnct;   /* Address of OP_OpenEphemeral opcode for tabTnct */
+};
+
 /*
 ** This routine generates the code for the inside of the inner loop
 ** of a SELECT.
@@ -96130,7 +94845,7 @@ static void selectInnerLoop(
   int srcTab,             /* Pull data from this table */
   int nColumn,            /* Number of columns in the source table */
   ExprList *pOrderBy,     /* If not NULL, sort results using this key */
-  int distinct,           /* If >=0, make sure results are distinct */
+  DistinctCtx *pDistinct, /* If not NULL, info on how to process DISTINCT */
   SelectDest *pDest,      /* How to dispose of the results */
   int iContinue,          /* Jump here to continue with next row */
   int iBreak              /* Jump here to break out of the inner loop */
@@ -96140,13 +94855,13 @@ static void selectInnerLoop(
   int hasDistinct;        /* True if the DISTINCT keyword is present */
   int regResult;              /* Start of memory holding result set */
   int eDest = pDest->eDest;   /* How to dispose of results */
-  int iParm = pDest->iParm;   /* First argument to disposal method */
+  int iParm = pDest->iSDParm; /* First argument to disposal method */
   int nResultCol;             /* Number of result columns */
 
   assert( v );
   if( NEVER(v==0) ) return;
   assert( pEList!=0 );
-  hasDistinct = distinct>=0;
+  hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP;
   if( pOrderBy==0 && !hasDistinct ){
     codeOffset(v, p, iContinue);
   }
@@ -96158,14 +94873,14 @@ static void selectInnerLoop(
   }else{
     nResultCol = pEList->nExpr;
   }
-  if( pDest->iMem==0 ){
-    pDest->iMem = pParse->nMem+1;
-    pDest->nMem = nResultCol;
+  if( pDest->iSdst==0 ){
+    pDest->iSdst = pParse->nMem+1;
+    pDest->nSdst = nResultCol;
     pParse->nMem += nResultCol;
   }else{ 
-    assert( pDest->nMem==nResultCol );
+    assert( pDest->nSdst==nResultCol );
   }
-  regResult = pDest->iMem;
+  regResult = pDest->iSdst;
   if( nColumn>0 ){
     for(i=0; i<nColumn; i++){
       sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i);
@@ -96186,7 +94901,55 @@ static void selectInnerLoop(
   if( hasDistinct ){
     assert( pEList!=0 );
     assert( pEList->nExpr==nColumn );
-    codeDistinct(pParse, distinct, iContinue, nColumn, regResult);
+    switch( pDistinct->eTnctType ){
+      case WHERE_DISTINCT_ORDERED: {
+        VdbeOp *pOp;            /* No longer required OpenEphemeral instr. */
+        int iJump;              /* Jump destination */
+        int regPrev;            /* Previous row content */
+
+        /* Allocate space for the previous row */
+        regPrev = pParse->nMem+1;
+        pParse->nMem += nColumn;
+
+        /* Change the OP_OpenEphemeral coded earlier to an OP_Null
+        ** sets the MEM_Cleared bit on the first register of the
+        ** previous value.  This will cause the OP_Ne below to always
+        ** fail on the first iteration of the loop even if the first
+        ** row is all NULLs.
+        */
+        sqlite3VdbeChangeToNoop(v, pDistinct->addrTnct);
+        pOp = sqlite3VdbeGetOp(v, pDistinct->addrTnct);
+        pOp->opcode = OP_Null;
+        pOp->p1 = 1;
+        pOp->p2 = regPrev;
+
+        iJump = sqlite3VdbeCurrentAddr(v) + nColumn;
+        for(i=0; i<nColumn; i++){
+          CollSeq *pColl = sqlite3ExprCollSeq(pParse, pEList->a[i].pExpr);
+          if( i<nColumn-1 ){
+            sqlite3VdbeAddOp3(v, OP_Ne, regResult+i, iJump, regPrev+i);
+          }else{
+            sqlite3VdbeAddOp3(v, OP_Eq, regResult+i, iContinue, regPrev+i);
+          }
+          sqlite3VdbeChangeP4(v, -1, (const char *)pColl, P4_COLLSEQ);
+          sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
+        }
+        assert( sqlite3VdbeCurrentAddr(v)==iJump );
+        sqlite3VdbeAddOp3(v, OP_Copy, regResult, regPrev, nColumn-1);
+        break;
+      }
+
+      case WHERE_DISTINCT_UNIQUE: {
+        sqlite3VdbeChangeToNoop(v, pDistinct->addrTnct);
+        break;
+      }
+
+      default: {
+        assert( pDistinct->eTnctType==WHERE_DISTINCT_UNORDERED );
+        codeDistinct(pParse, pDistinct->tabTnct, iContinue, nColumn, regResult);
+        break;
+      }
+    }
     if( pOrderBy==0 ){
       codeOffset(v, p, iContinue);
     }
@@ -96244,7 +95007,8 @@ static void selectInnerLoop(
     */
     case SRT_Set: {
       assert( nColumn==1 );
-      p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affinity);
+      pDest->affSdst =
+                  sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst);
       if( pOrderBy ){
         /* At first glance you would think we could optimize out the
         ** ORDER BY in this case since the order of entries in the set
@@ -96253,7 +95017,7 @@ static void selectInnerLoop(
         pushOntoSorter(pParse, pOrderBy, p, regResult);
       }else{
         int r1 = sqlite3GetTempReg(pParse);
-        sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, 1, r1, &p->affinity, 1);
+        sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult,1,r1, &pDest->affSdst, 1);
         sqlite3ExprCacheAffinityChange(pParse, regResult, 1);
         sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1);
         sqlite3ReleaseTempReg(pParse, r1);
@@ -96299,7 +95063,7 @@ static void selectInnerLoop(
         pushOntoSorter(pParse, pOrderBy, p, r1);
         sqlite3ReleaseTempReg(pParse, r1);
       }else if( eDest==SRT_Coroutine ){
-        sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm);
+        sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
       }else{
         sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nColumn);
         sqlite3ExprCacheAffinityChange(pParse, regResult, nColumn);
@@ -96479,7 +95243,7 @@ static void generateSortTail(
   ExprList *pOrderBy = p->pOrderBy;
 
   int eDest = pDest->eDest;
-  int iParm = pDest->iParm;
+  int iParm = pDest->iSDParm;
 
   int regRow;
   int regRowid;
@@ -96520,7 +95284,8 @@ static void generateSortTail(
 #ifndef SQLITE_OMIT_SUBQUERY
     case SRT_Set: {
       assert( nColumn==1 );
-      sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid, &p->affinity, 1);
+      sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid,
+                        &pDest->affSdst, 1);
       sqlite3ExprCacheAffinityChange(pParse, regRow, 1);
       sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRowid);
       break;
@@ -96538,17 +95303,17 @@ static void generateSortTail(
       testcase( eDest==SRT_Output );
       testcase( eDest==SRT_Coroutine );
       for(i=0; i<nColumn; i++){
-        assert( regRow!=pDest->iMem+i );
-        sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iMem+i);
+        assert( regRow!=pDest->iSdst+i );
+        sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iSdst+i);
         if( i==0 ){
           sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
         }
       }
       if( eDest==SRT_Output ){
-        sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iMem, nColumn);
-        sqlite3ExprCacheAffinityChange(pParse, pDest->iMem, nColumn);
+        sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn);
+        sqlite3ExprCacheAffinityChange(pParse, pDest->iSdst, nColumn);
       }else{
-        sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm);
+        sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
       }
       break;
     }
@@ -96835,7 +95600,7 @@ static void generateColumnNames(
 static int selectColumnsFromExprList(
   Parse *pParse,          /* Parsing context */
   ExprList *pEList,       /* Expr list from which to derive column names */
-  int *pnCol,             /* Write the number of columns here */
+  i16 *pnCol,             /* Write the number of columns here */
   Column **paCol          /* Write the new column list here */
 ){
   sqlite3 *db = pParse->db;   /* Database connection */
@@ -96861,7 +95626,7 @@ static int selectColumnsFromExprList(
   for(i=0, pCol=aCol; i<nCol; i++, pCol++){
     /* Get an appropriate name for the column
     */
-    p = pEList->a[i].pExpr;
+    p = sqlite3ExprSkipCollate(pEList->a[i].pExpr);
     assert( p->pRight==0 || ExprHasProperty(p->pRight, EP_IntValue)
                || p->pRight->u.zToken==0 || p->pRight->u.zToken[0]!=0 );
     if( (zName = pEList->a[i].zName)!=0 ){
@@ -97199,7 +95964,7 @@ static int multiSelect(
   */
   if( dest.eDest==SRT_EphemTab ){
     assert( p->pEList );
-    sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iParm, p->pEList->nExpr);
+    sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr);
     sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
     dest.eDest = SRT_Table;
   }
@@ -97285,7 +96050,7 @@ static int multiSelect(
                                      ** of a 3-way or more compound */
         assert( p->pLimit==0 );      /* Not allowed on leftward elements */
         assert( p->pOffset==0 );     /* Not allowed on leftward elements */
-        unionTab = dest.iParm;
+        unionTab = dest.iSDParm;
       }else{
         /* We will need to create our own temporary table to hold the
         ** intermediate results.
@@ -97342,7 +96107,7 @@ static int multiSelect(
       /* Convert the data in the temporary table into whatever form
       ** it is that we currently need.
       */
-      assert( unionTab==dest.iParm || dest.eDest!=priorOp );
+      assert( unionTab==dest.iSDParm || dest.eDest!=priorOp );
       if( dest.eDest!=priorOp ){
         int iCont, iBreak, iStart;
         assert( p->pEList );
@@ -97357,7 +96122,7 @@ static int multiSelect(
         sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak);
         iStart = sqlite3VdbeCurrentAddr(v);
         selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
-                        0, -1, &dest, iCont, iBreak);
+                        0, 0, &dest, iCont, iBreak);
         sqlite3VdbeResolveLabel(v, iCont);
         sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart);
         sqlite3VdbeResolveLabel(v, iBreak);
@@ -97406,7 +96171,7 @@ static int multiSelect(
       p->pLimit = 0;
       pOffset = p->pOffset;
       p->pOffset = 0;
-      intersectdest.iParm = tab2;
+      intersectdest.iSDParm = tab2;
       explainSetInteger(iSub2, pParse->iNextSelectId);
       rc = sqlite3Select(pParse, p, &intersectdest);
       testcase( rc!=SQLITE_OK );
@@ -97435,7 +96200,7 @@ static int multiSelect(
       sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0);
       sqlite3ReleaseTempReg(pParse, r1);
       selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
-                      0, -1, &dest, iCont, iBreak);
+                      0, 0, &dest, iCont, iBreak);
       sqlite3VdbeResolveLabel(v, iCont);
       sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart);
       sqlite3VdbeResolveLabel(v, iBreak);
@@ -97481,6 +96246,7 @@ static int multiSelect(
         *apColl = db->pDfltColl;
       }
     }
+    pKeyInfo->aSortOrder = (u8*)apColl;
 
     for(pLoop=p; pLoop; pLoop=pLoop->pPrior){
       for(i=0; i<2; i++){
@@ -97500,8 +96266,8 @@ static int multiSelect(
   }
 
 multi_select_end:
-  pDest->iMem = dest.iMem;
-  pDest->nMem = dest.nMem;
+  pDest->iSdst = dest.iSdst;
+  pDest->nSdst = dest.nSdst;
   sqlite3SelectDelete(db, pDelete);
   return rc;
 }
@@ -97511,8 +96277,8 @@ multi_select_end:
 ** Code an output subroutine for a coroutine implementation of a
 ** SELECT statment.
 **
-** The data to be output is contained in pIn->iMem.  There are
-** pIn->nMem columns to be output.  pDest is where the output should
+** The data to be output is contained in pIn->iSdst.  There are
+** pIn->nSdst columns to be output.  pDest is where the output should
 ** be sent.
 **
 ** regReturn is the number of the register holding the subroutine
@@ -97550,16 +96316,16 @@ static int generateOutputSubroutine(
   if( regPrev ){
     int j1, j2;
     j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev);
-    j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iMem, regPrev+1, pIn->nMem,
+    j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst,
                               (char*)pKeyInfo, p4type);
     sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2);
     sqlite3VdbeJumpHere(v, j1);
-    sqlite3ExprCodeCopy(pParse, pIn->iMem, regPrev+1, pIn->nMem);
+    sqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1);
     sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev);
   }
   if( pParse->db->mallocFailed ) return 0;
 
-  /* Suppress the the first OFFSET entries if there is an OFFSET clause
+  /* Suppress the first OFFSET entries if there is an OFFSET clause
   */
   codeOffset(v, p, iContinue);
 
@@ -97572,9 +96338,9 @@ static int generateOutputSubroutine(
       int r2 = sqlite3GetTempReg(pParse);
       testcase( pDest->eDest==SRT_Table );
       testcase( pDest->eDest==SRT_EphemTab );
-      sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iMem, pIn->nMem, r1);
-      sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iParm, r2);
-      sqlite3VdbeAddOp3(v, OP_Insert, pDest->iParm, r1, r2);
+      sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1);
+      sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iSDParm, r2);
+      sqlite3VdbeAddOp3(v, OP_Insert, pDest->iSDParm, r1, r2);
       sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
       sqlite3ReleaseTempReg(pParse, r2);
       sqlite3ReleaseTempReg(pParse, r1);
@@ -97588,13 +96354,13 @@ static int generateOutputSubroutine(
     */
     case SRT_Set: {
       int r1;
-      assert( pIn->nMem==1 );
-      p->affinity = 
-         sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affinity);
+      assert( pIn->nSdst==1 );
+      pDest->affSdst = 
+         sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affSdst);
       r1 = sqlite3GetTempReg(pParse);
-      sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iMem, 1, r1, &p->affinity, 1);
-      sqlite3ExprCacheAffinityChange(pParse, pIn->iMem, 1);
-      sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iParm, r1);
+      sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, 1, r1, &pDest->affSdst,1);
+      sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, 1);
+      sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iSDParm, r1);
       sqlite3ReleaseTempReg(pParse, r1);
       break;
     }
@@ -97603,7 +96369,7 @@ static int generateOutputSubroutine(
     /* If any row exist in the result set, record that fact and abort.
     */
     case SRT_Exists: {
-      sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iParm);
+      sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iSDParm);
       /* The LIMIT clause will terminate the loop for us */
       break;
     }
@@ -97614,23 +96380,23 @@ static int generateOutputSubroutine(
     ** of the scan loop.
     */
     case SRT_Mem: {
-      assert( pIn->nMem==1 );
-      sqlite3ExprCodeMove(pParse, pIn->iMem, pDest->iParm, 1);
+      assert( pIn->nSdst==1 );
+      sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, 1);
       /* The LIMIT clause will jump out of the loop for us */
       break;
     }
 #endif /* #ifndef SQLITE_OMIT_SUBQUERY */
 
     /* The results are stored in a sequence of registers
-    ** starting at pDest->iMem.  Then the co-routine yields.
+    ** starting at pDest->iSdst.  Then the co-routine yields.
     */
     case SRT_Coroutine: {
-      if( pDest->iMem==0 ){
-        pDest->iMem = sqlite3GetTempRange(pParse, pIn->nMem);
-        pDest->nMem = pIn->nMem;
+      if( pDest->iSdst==0 ){
+        pDest->iSdst = sqlite3GetTempRange(pParse, pIn->nSdst);
+        pDest->nSdst = pIn->nSdst;
       }
-      sqlite3ExprCodeMove(pParse, pIn->iMem, pDest->iMem, pDest->nMem);
-      sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm);
+      sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pDest->nSdst);
+      sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
       break;
     }
 
@@ -97644,8 +96410,8 @@ static int generateOutputSubroutine(
     */
     default: {
       assert( pDest->eDest==SRT_Output );
-      sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iMem, pIn->nMem);
-      sqlite3ExprCacheAffinityChange(pParse, pIn->iMem, pIn->nMem);
+      sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iSdst, pIn->nSdst);
+      sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst);
       break;
     }
   }
@@ -97858,12 +96624,13 @@ static int multiSelectOrderBy(
       for(i=0; i<nOrderBy; i++){
         CollSeq *pColl;
         Expr *pTerm = pOrderBy->a[i].pExpr;
-        if( pTerm->flags & EP_ExpCollate ){
-          pColl = pTerm->pColl;
+        if( pTerm->flags & EP_Collate ){
+          pColl = sqlite3ExprCollSeq(pParse, pTerm);
         }else{
           pColl = multiSelectCollSeq(pParse, p, aPermute[i]);
-          pTerm->flags |= EP_ExpCollate;
-          pTerm->pColl = pColl;
+          if( pColl==0 ) pColl = db->pDfltColl;
+          pOrderBy->a[i].pExpr =
+             sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName);
         }
         pKeyMerge->aColl[i] = pColl;
         pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder;
@@ -98064,8 +96831,9 @@ static int multiSelectOrderBy(
   */
   sqlite3VdbeResolveLabel(v, labelCmpr);
   sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);
-  sqlite3VdbeAddOp4(v, OP_Compare, destA.iMem, destB.iMem, nOrderBy,
+  sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy,
                          (char*)pKeyMerge, P4_KEYINFO_HANDOFF);
+  sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE);
   sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
 
   /* Release temporary registers
@@ -98133,9 +96901,6 @@ static Expr *substExpr(
       assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
       assert( pExpr->pLeft==0 && pExpr->pRight==0 );
       pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0);
-      if( pNew && pExpr->pColl ){
-        pNew->pColl = pExpr->pColl;
-      }
       sqlite3ExprDelete(db, pExpr);
       pExpr = pNew;
     }
@@ -98278,6 +97043,12 @@ static void substSelect(
 **        operators have an implied DISTINCT which is disallowed by
 **        restriction (4).
 **
+**        Also, each component of the sub-query must return the same number
+**        of result columns. This is actually a requirement for any compound
+**        SELECT statement, but all the code here does is make sure that no
+**        such (illegal) sub-query is flattened. The caller will detect the
+**        syntax error and return a detailed message.
+**
 **  (18)  If the sub-query is a compound select, then all terms of the
 **        ORDER by clause of the parent must be simple references to 
 **        columns of the sub-query.
@@ -98328,7 +97099,7 @@ static int flattenSubquery(
   */
   assert( p!=0 );
   assert( p->pPrior==0 );  /* Unable to flatten compound queries */
-  if( db->flags & SQLITE_QueryFlattener ) return 0;
+  if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0;
   pSrc = p->pSrc;
   assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
   pSubitem = &pSrc->a[iFrom];
@@ -98421,6 +97192,7 @@ static int flattenSubquery(
       if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0
        || (pSub1->pPrior && pSub1->op!=TK_ALL) 
        || pSub1->pSrc->nSrc<1
+       || pSub->pEList->nExpr!=pSub1->pEList->nExpr
       ){
         return 0;
       }
@@ -98616,10 +97388,9 @@ static int flattenSubquery(
     pList = pParent->pEList;
     for(i=0; i<pList->nExpr; i++){
       if( pList->a[i].zName==0 ){
-        const char *zSpan = pList->a[i].zSpan;
-        if( ALWAYS(zSpan) ){
-          pList->a[i].zName = sqlite3DbStrDup(db, zSpan);
-        }
+        char *zName = sqlite3DbStrDup(db, pList->a[i].zSpan);
+        sqlite3Dequote(zName);
+        pList->a[i].zName = zName;
       }
     }
     substExprList(db, pParent->pEList, iParent, pSub->pEList);
@@ -98738,7 +97509,7 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){
 
   if( IsVirtual(pTab) ) return 0;
   if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
-  if( pAggInfo->nFunc==0 ) return 0;
+  if( NEVER(pAggInfo->nFunc==0) ) return 0;
   if( (pAggInfo->aFunc[0].pFunc->flags&SQLITE_FUNC_COUNT)==0 ) return 0;
   if( pExpr->flags&EP_Distinct ) return 0;
 
@@ -98850,8 +97621,7 @@ static int selectExpander(Walker *pWalker, Select *p){
     }else{
       /* An ordinary table or view name in the FROM clause */
       assert( pFrom->pTab==0 );
-      pFrom->pTab = pTab = 
-        sqlite3LocateTable(pParse,0,pFrom->zName,pFrom->zDatabase);
+      pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom);
       if( pTab==0 ) return WRC_Abort;
       pTab->nRef++;
 #if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
@@ -99110,7 +97880,7 @@ static void sqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){
 
 
 /*
-** This routine sets of a SELECT statement for processing.  The
+** This routine sets up a SELECT statement for processing.  The
 ** following is accomplished:
 **
 **     *  VDBE Cursor numbers are assigned to all FROM-clause terms.
@@ -99142,7 +97912,8 @@ SQLITE_PRIVATE void sqlite3SelectPrep(
 **
 ** The aggregate accumulator is a set of memory cells that hold
 ** intermediate results while calculating an aggregate.  This
-** routine simply stores NULLs in all of those memory cells.
+** routine generates code that stores NULLs in all of those memory
+** cells.
 */
 static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
   Vdbe *v = pParse->pVdbe;
@@ -99310,23 +98081,24 @@ static void explainSimpleCount(
 **
 **     SRT_Mem         Only valid if the result is a single column.
 **                     Store the first column of the first result row
-**                     in register pDest->iParm then abandon the rest
+**                     in register pDest->iSDParm then abandon the rest
 **                     of the query.  This destination implies "LIMIT 1".
 **
 **     SRT_Set         The result must be a single column.  Store each
-**                     row of result as the key in table pDest->iParm. 
-**                     Apply the affinity pDest->affinity before storing
+**                     row of result as the key in table pDest->iSDParm. 
+**                     Apply the affinity pDest->affSdst before storing
 **                     results.  Used to implement "IN (SELECT ...)".
 **
-**     SRT_Union       Store results as a key in a temporary table pDest->iParm.
+**     SRT_Union       Store results as a key in a temporary table 
+**                     identified by pDest->iSDParm.
 **
-**     SRT_Except      Remove results from the temporary table pDest->iParm.
+**     SRT_Except      Remove results from the temporary table pDest->iSDParm.
 **
-**     SRT_Table       Store results in temporary table pDest->iParm.
+**     SRT_Table       Store results in temporary table pDest->iSDParm.
 **                     This is like SRT_EphemTab except that the table
 **                     is assumed to already be open.
 **
-**     SRT_EphemTab    Create an temporary table pDest->iParm and store
+**     SRT_EphemTab    Create an temporary table pDest->iSDParm and store
 **                     the result there. The cursor is left open after
 **                     returning.  This is like SRT_Table except that
 **                     this destination uses OP_OpenEphemeral to create
@@ -99334,9 +98106,9 @@ static void explainSimpleCount(
 **
 **     SRT_Coroutine   Generate a co-routine that returns a new row of
 **                     results each time it is invoked.  The entry point
-**                     of the co-routine is stored in register pDest->iParm.
+**                     of the co-routine is stored in register pDest->iSDParm.
 **
-**     SRT_Exists      Store a 1 in memory cell pDest->iParm if the result
+**     SRT_Exists      Store a 1 in memory cell pDest->iSDParm if the result
 **                     set is not empty.
 **
 **     SRT_Discard     Throw the results away.  This is used by SELECT
@@ -99365,11 +98137,9 @@ SQLITE_PRIVATE int sqlite3Select(
   ExprList *pOrderBy;    /* The ORDER BY clause.  May be NULL */
   ExprList *pGroupBy;    /* The GROUP BY clause.  May be NULL */
   Expr *pHaving;         /* The HAVING clause.  May be NULL */
-  int isDistinct;        /* True if the DISTINCT keyword is present */
-  int distinct;          /* Table to use for the distinct set */
   int rc = 1;            /* Value to return from this function */
   int addrSortIndex;     /* Address of an OP_OpenEphemeral instruction */
-  int addrDistinctIndex; /* Address of an OP_OpenEphemeral instruction */
+  DistinctCtx sDistinct; /* Info on how to code the DISTINCT keyword */
   AggInfo sAggInfo;      /* Information used by aggregate queries */
   int iEnd;              /* Address of the end of the query */
   sqlite3 *db;           /* The database connection */
@@ -99429,8 +98199,17 @@ SQLITE_PRIVATE int sqlite3Select(
     int isAggSub;
 
     if( pSub==0 ) continue;
+
+    /* Sometimes the code for a subquery will be generated more than
+    ** once, if the subquery is part of the WHERE clause in a LEFT JOIN,
+    ** for example.  In that case, do not regenerate the code to manifest
+    ** a view or the co-routine to implement a view.  The first instance
+    ** is sufficient, though the subroutine to manifest the view does need
+    ** to be invoked again. */
     if( pItem->addrFillSub ){
-      sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
+      if( pItem->viaCoroutine==0 ){
+        sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
+      }
       continue;
     }
 
@@ -99451,6 +98230,44 @@ SQLITE_PRIVATE int sqlite3Select(
         p->selFlags |= SF_Aggregate;
       }
       i = -1;
+    }else if( pTabList->nSrc==1 && (p->selFlags & SF_Materialize)==0
+      && OptimizationEnabled(db, SQLITE_SubqCoroutine)
+    ){
+      /* Implement a co-routine that will return a single row of the result
+      ** set on each invocation.
+      */
+      int addrTop;
+      int addrEof;
+      pItem->regReturn = ++pParse->nMem;
+      addrEof = ++pParse->nMem;
+      /* Before coding the OP_Goto to jump to the start of the main routine,
+      ** ensure that the jump to the verify-schema routine has already
+      ** been coded. Otherwise, the verify-schema would likely be coded as 
+      ** part of the co-routine. If the main routine then accessed the 
+      ** database before invoking the co-routine for the first time (for 
+      ** example to initialize a LIMIT register from a sub-select), it would 
+      ** be doing so without having verified the schema version and obtained 
+      ** the required db locks. See ticket d6b36be38.  */
+      sqlite3CodeVerifySchema(pParse, -1);
+      sqlite3VdbeAddOp0(v, OP_Goto);
+      addrTop = sqlite3VdbeAddOp1(v, OP_OpenPseudo, pItem->iCursor);
+      sqlite3VdbeChangeP5(v, 1);
+      VdbeComment((v, "coroutine for %s", pItem->pTab->zName));
+      pItem->addrFillSub = addrTop;
+      sqlite3VdbeAddOp2(v, OP_Integer, 0, addrEof);
+      sqlite3VdbeChangeP5(v, 1);
+      sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
+      explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
+      sqlite3Select(pParse, pSub, &dest);
+      pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow;
+      pItem->viaCoroutine = 1;
+      sqlite3VdbeChangeP2(v, addrTop, dest.iSdst);
+      sqlite3VdbeChangeP3(v, addrTop, dest.nSdst);
+      sqlite3VdbeAddOp2(v, OP_Integer, 1, addrEof);
+      sqlite3VdbeAddOp1(v, OP_Yield, pItem->regReturn);
+      VdbeComment((v, "end %s", pItem->pTab->zName));
+      sqlite3VdbeJumpHere(v, addrTop-1);
+      sqlite3ClearTempRegCache(pParse);
     }else{
       /* Generate a subroutine that will fill an ephemeral table with
       ** the content of this subquery.  pItem->addrFillSub will point
@@ -99495,7 +98312,7 @@ SQLITE_PRIVATE int sqlite3Select(
   pWhere = p->pWhere;
   pGroupBy = p->pGroupBy;
   pHaving = p->pHaving;
-  isDistinct = (p->selFlags & SF_Distinct)!=0;
+  sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0;
 
 #ifndef SQLITE_OMIT_COMPOUND_SELECT
   /* If there is are a sequence of queries, do the earlier ones first.
@@ -99530,7 +98347,7 @@ SQLITE_PRIVATE int sqlite3Select(
   ** to disable this optimization for testing purposes.
   */
   if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy)==0
-         && (db->flags & SQLITE_GroupByOrder)==0 ){
+         && OptimizationEnabled(db, SQLITE_GroupByOrder) ){
     pOrderBy = 0;
   }
 
@@ -99556,6 +98373,10 @@ SQLITE_PRIVATE int sqlite3Select(
     p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
     pGroupBy = p->pGroupBy;
     pOrderBy = 0;
+    /* Notice that even thought SF_Distinct has been cleared from p->selFlags,
+    ** the sDistinct.isTnct is still set.  Hence, isTnct represents the
+    ** original setting of the SF_Distinct flag, not the current setting */
+    assert( sDistinct.isTnct );
   }
 
   /* If there is an ORDER BY clause, then this sorting
@@ -99580,7 +98401,7 @@ SQLITE_PRIVATE int sqlite3Select(
   /* If the output is destined for a temporary table, open that table.
   */
   if( pDest->eDest==SRT_EphemTab ){
-    sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iParm, pEList->nExpr);
+    sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr);
   }
 
   /* Set the limiter.
@@ -99596,24 +98417,27 @@ SQLITE_PRIVATE int sqlite3Select(
   /* Open a virtual index to use for the distinct set.
   */
   if( p->selFlags & SF_Distinct ){
-    KeyInfo *pKeyInfo;
-    distinct = pParse->nTab++;
-    pKeyInfo = keyInfoFromExprList(pParse, p->pEList);
-    addrDistinctIndex = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, distinct, 0, 0,
-        (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
+    sDistinct.tabTnct = pParse->nTab++;
+    sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
+                                sDistinct.tabTnct, 0, 0,
+                                (char*)keyInfoFromExprList(pParse, p->pEList),
+                                P4_KEYINFO_HANDOFF);
     sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
+    sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED;
   }else{
-    distinct = addrDistinctIndex = -1;
+    sDistinct.eTnctType = WHERE_DISTINCT_NOOP;
   }
 
-  /* Aggregate and non-aggregate queries are handled differently */
   if( !isAgg && pGroupBy==0 ){
-    ExprList *pDist = (isDistinct ? p->pEList : 0);
+    /* No aggregate functions and no GROUP BY clause */
+    ExprList *pDist = (sDistinct.isTnct ? p->pEList : 0);
 
     /* Begin the database scan. */
-    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pOrderBy, pDist, 0);
+    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pOrderBy, pDist, 0,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 sorting index that was created by a prior OP_OpenEphemeral 
     ** instruction ended up not being needed, then change the OP_OpenEphemeral
@@ -99624,59 +98448,16 @@ SQLITE_PRIVATE int sqlite3Select(
       p->addrOpenEphm[2] = -1;
     }
 
-    if( pWInfo->eDistinct ){
-      VdbeOp *pOp;                /* No longer required OpenEphemeral instr. */
-     
-      assert( addrDistinctIndex>=0 );
-      pOp = sqlite3VdbeGetOp(v, addrDistinctIndex);
-
-      assert( isDistinct );
-      assert( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED 
-           || pWInfo->eDistinct==WHERE_DISTINCT_UNIQUE 
-      );
-      distinct = -1;
-      if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED ){
-        int iJump;
-        int iExpr;
-        int iFlag = ++pParse->nMem;
-        int iBase = pParse->nMem+1;
-        int iBase2 = iBase + pEList->nExpr;
-        pParse->nMem += (pEList->nExpr*2);
-
-        /* Change the OP_OpenEphemeral coded earlier to an OP_Integer. The
-        ** OP_Integer initializes the "first row" flag.  */
-        pOp->opcode = OP_Integer;
-        pOp->p1 = 1;
-        pOp->p2 = iFlag;
-
-        sqlite3ExprCodeExprList(pParse, pEList, iBase, 1);
-        iJump = sqlite3VdbeCurrentAddr(v) + 1 + pEList->nExpr + 1 + 1;
-        sqlite3VdbeAddOp2(v, OP_If, iFlag, iJump-1);
-        for(iExpr=0; iExpr<pEList->nExpr; iExpr++){
-          CollSeq *pColl = sqlite3ExprCollSeq(pParse, pEList->a[iExpr].pExpr);
-          sqlite3VdbeAddOp3(v, OP_Ne, iBase+iExpr, iJump, iBase2+iExpr);
-          sqlite3VdbeChangeP4(v, -1, (const char *)pColl, P4_COLLSEQ);
-          sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
-        }
-        sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iContinue);
-
-        sqlite3VdbeAddOp2(v, OP_Integer, 0, iFlag);
-        assert( sqlite3VdbeCurrentAddr(v)==iJump );
-        sqlite3VdbeAddOp3(v, OP_Move, iBase, iBase2, pEList->nExpr);
-      }else{
-        pOp->opcode = OP_Noop;
-      }
-    }
-
     /* Use the standard inner loop. */
-    selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, pDest,
+    selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, &sDistinct, pDest,
                     pWInfo->iContinue, pWInfo->iBreak);
 
     /* End the database scan loop.
     */
     sqlite3WhereEnd(pWInfo);
   }else{
-    /* This is the processing for aggregate queries */
+    /* This case when there exist aggregate functions or a GROUP BY clause
+    ** or both */
     NameContext sNC;    /* Name context for processing aggregate information */
     int iAMem;          /* First Mem address for storing current GROUP BY */
     int iBMem;          /* First Mem address for previous GROUP BY */
@@ -99784,14 +98565,13 @@ 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);
+      pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, 0, 0);
       if( pWInfo==0 ) goto select_end;
-      if( pGroupBy==0 ){
+      if( pWInfo->nOBSat==pGroupBy->nExpr ){
         /* 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
         */
-        pGroupBy = p->pGroupBy;
         groupBySort = 0;
       }else{
         /* Rows are coming out in undetermined order.  We have to push
@@ -99805,7 +98585,8 @@ SQLITE_PRIVATE int sqlite3Select(
         int nGroupBy;
 
         explainTempTable(pParse, 
-            isDistinct && !(p->selFlags&SF_Distinct)?"DISTINCT":"GROUP BY");
+            (sDistinct.isTnct && (p->selFlags&SF_Distinct)==0) ?
+                    "DISTINCT" : "GROUP BY");
 
         groupBySort = 1;
         nGroupBy = pGroupBy->nExpr;
@@ -99937,7 +98718,7 @@ SQLITE_PRIVATE int sqlite3Select(
       finalizeAggFunctions(pParse, &sAggInfo);
       sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
       selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy,
-                      distinct, pDest,
+                      &sDistinct, pDest,
                       addrOutputRow+1, addrSetAbort);
       sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
       VdbeComment((v, "end groupby result generator"));
@@ -100040,6 +98821,7 @@ SQLITE_PRIVATE int sqlite3Select(
         u8 flag = minMaxQuery(p);
         if( flag ){
           assert( !ExprHasProperty(p->pEList->a[0].pExpr, EP_xIsSelect) );
+          assert( p->pEList->a[0].pExpr->x.pList->nExpr==1 );
           pMinMax = sqlite3ExprListDup(db, p->pEList->a[0].pExpr->x.pList,0);
           pDel = pMinMax;
           if( pMinMax && !db->mallocFailed ){
@@ -100053,13 +98835,14 @@ SQLITE_PRIVATE int sqlite3Select(
         ** of output.
         */
         resetAccumulator(pParse, &sAggInfo);
-        pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pMinMax, 0, flag);
+        pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMax,0,flag,0);
         if( pWInfo==0 ){
           sqlite3ExprListDelete(db, pDel);
           goto select_end;
         }
         updateAccumulator(pParse, &sAggInfo);
-        if( !pMinMax && flag ){
+        assert( pMinMax==0 || pMinMax->nExpr==1 );
+        if( pWInfo->nOBSat>0 ){
           sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iBreak);
           VdbeComment((v, "%s() by index",
                 (flag==WHERE_ORDERBY_MIN?"min":"max")));
@@ -100070,7 +98853,7 @@ SQLITE_PRIVATE int sqlite3Select(
 
       pOrderBy = 0;
       sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL);
-      selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, -1
+      selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, 0
                       pDest, addrEnd, addrEnd);
       sqlite3ExprListDelete(db, pDel);
     }
@@ -100078,7 +98861,7 @@ SQLITE_PRIVATE int sqlite3Select(
     
   } /* endif aggregate query */
 
-  if( distinct>=0 ){
+  if( sDistinct.eTnctType==WHERE_DISTINCT_UNORDERED ){
     explainTempTable(pParse, "DISTINCT");
   }
 
@@ -100525,7 +99308,7 @@ SQLITE_PRIVATE void sqlite3BeginTrigger(
     iDb = 1;
     pName = pName1;
   }else{
-    /* Figure out the db that the the trigger will be created in */
+    /* Figure out the db that the trigger will be created in */
     iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
     if( iDb<0 ){
       goto trigger_cleanup;
@@ -101143,6 +99926,15 @@ static int codeTriggerProgram(
     */
     pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf;
 
+    /* Clear the cookieGoto flag. When coding triggers, the cookieGoto 
+    ** variable is used as a flag to indicate to sqlite3ExprCodeConstants()
+    ** that it is not safe to refactor constants (this happens after the
+    ** start of the first loop in the SQL statement is coded - at that 
+    ** point code may be conditionally executed, so it is no longer safe to 
+    ** initialize constant register values).  */
+    assert( pParse->cookieGoto==0 || pParse->cookieGoto==-1 );
+    pParse->cookieGoto = 0;
+
     switch( pStep->op ){
       case TK_UPDATE: {
         sqlite3Update(pParse, 
@@ -101853,7 +100645,7 @@ SQLITE_PRIVATE void sqlite3Update(
   */
   sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid);
   pWInfo = sqlite3WhereBegin(
-      pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED
+      pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED, 0
   );
   if( pWInfo==0 ) goto update_cleanup;
   okOnePass = pWInfo->okOnePass;
@@ -102299,6 +101091,7 @@ SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse){
   Vdbe *v = sqlite3GetVdbe(pParse);
   if( v ){
     sqlite3VdbeAddOp2(v, OP_Vacuum, 0, 0);
+    sqlite3VdbeUsesBtree(v, 0);
   }
   return;
 }
@@ -102694,7 +101487,7 @@ SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *pVTab){
 
   assert( db );
   assert( pVTab->nRef>0 );
-  assert( sqlite3SafetyCheckOk(db) );
+  assert( db->magic==SQLITE_MAGIC_OPEN || db->magic==SQLITE_MAGIC_ZOMBIE );
 
   pVTab->nRef--;
   if( pVTab->nRef==0 ){
@@ -102827,7 +101620,7 @@ SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table *p){
   if( p->azModuleArg ){
     int i;
     for(i=0; i<p->nModuleArg; i++){
-      sqlite3DbFree(db, p->azModuleArg[i]);
+      if( i!=1 ) sqlite3DbFree(db, p->azModuleArg[i]);
     }
     sqlite3DbFree(db, p->azModuleArg);
   }
@@ -102887,7 +101680,7 @@ SQLITE_PRIVATE void sqlite3VtabBeginParse(
   pTable->tabFlags |= TF_Virtual;
   pTable->nModuleArg = 0;
   addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
-  addModuleArgument(db, pTable, sqlite3DbStrDup(db, db->aDb[iDb].zName));
+  addModuleArgument(db, pTable, 0);
   addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
   pParse->sNameToken.n = (int)(&pModuleName->z[pModuleName->n] - pName1->z);
 
@@ -103044,6 +101837,7 @@ static int vtabCallConstructor(
   int nArg = pTab->nModuleArg;
   char *zErr = 0;
   char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
+  int iDb;
 
   if( !zModuleName ){
     return SQLITE_NOMEM;
@@ -103057,6 +101851,9 @@ static int vtabCallConstructor(
   pVTable->db = db;
   pVTable->pMod = pMod;
 
+  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+  pTab->azModuleArg[1] = db->aDb[iDb].zName;
+
   /* Invoke the virtual table constructor */
   assert( &db->pVtabCtx );
   assert( xConstruct );
@@ -103091,7 +101888,7 @@ static int vtabCallConstructor(
       /* If everything went according to plan, link the new VTable structure
       ** into the linked list headed by pTab->pVTable. Then loop through the 
       ** columns of the table to see if any of them contain the token "hidden".
-      ** If so, set the Column.isHidden flag and remove the token from
+      ** If so, set the Column COLFLAG_HIDDEN flag and remove the token from
       ** the type string.  */
       pVTable->pNext = pTab->pVTable;
       pTab->pVTable = pVTable;
@@ -103122,7 +101919,7 @@ static int vtabCallConstructor(
             assert(zType[i-1]==' ');
             zType[i-1] = '\0';
           }
-          pTab->aCol[iCol].isHidden = 1;
+          pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN;
         }
       }
     }
@@ -103683,9 +102480,10 @@ SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){
 ** Trace output macros
 */
 #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
-SQLITE_PRIVATE int sqlite3WhereTrace = 0;
+/***/ int sqlite3WhereTrace = 0;
 #endif
-#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
+#if defined(SQLITE_DEBUG) \
+    && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE))
 # define WHERETRACE(X)  if(sqlite3WhereTrace) sqlite3DebugPrintf X
 #else
 # define WHERETRACE(X)
@@ -103916,14 +102714,49 @@ struct WhereCost {
 #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     0x00800000  /* Use index only - omit table */
-#define WHERE_ORDERBY      0x01000000  /* Output will appear in correct order */
-#define WHERE_REVERSE      0x02000000  /* Scan in reverse order */
-#define WHERE_UNIQUE       0x04000000  /* Selects no more than one row */
+#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_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.
+*/
+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 */
+};
+
+/*
+** Return TRUE if the probe cost is less than the baseline cost
+*/
+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;
+}
 
 /*
 ** Initialize a preallocated WhereClause structure.
@@ -104187,23 +103020,32 @@ static int allowedOp(int op){
 ** Commute a comparison operator.  Expressions of the form "X op Y"
 ** are converted into "Y op X".
 **
-** If a collation sequence is associated with either the left or right
+** If left/right precendence 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 collate NOCASE op Y". This is because any collation sequence on
+** "X op Y". This is 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_ExpCollate flag
+** attached to the right. For the same reason the EP_Collate flag
 ** is not commuted.
 */
 static void exprCommute(Parse *pParse, Expr *pExpr){
-  u16 expRight = (pExpr->pRight->flags & EP_ExpCollate);
-  u16 expLeft = (pExpr->pLeft->flags & EP_ExpCollate);
+  u16 expRight = (pExpr->pRight->flags & EP_Collate);
+  u16 expLeft = (pExpr->pLeft->flags & EP_Collate);
   assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN );
-  pExpr->pRight->pColl = sqlite3ExprCollSeq(pParse, pExpr->pRight);
-  pExpr->pLeft->pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
-  SWAP(CollSeq*,pExpr->pRight->pColl,pExpr->pLeft->pColl);
-  pExpr->pRight->flags = (pExpr->pRight->flags & ~EP_ExpCollate) | expLeft;
-  pExpr->pLeft->flags = (pExpr->pLeft->flags & ~EP_ExpCollate) | expRight;
+  if( expRight==expLeft ){
+    /* Either X and Y both have COLLATE operator or neither do */
+    if( expRight ){
+      /* Both X and Y have COLLATE operators.  Make sure X is always
+      ** used by clearing the EP_Collate flag from Y. */
+      pExpr->pRight->flags &= ~EP_Collate;
+    }else if( sqlite3ExprCollSeq(pParse, pExpr->pLeft)!=0 ){
+      /* Neither X nor Y have COLLATE operators, but X has a non-default
+      ** collating sequence.  So add the EP_Collate marker on X to cause
+      ** it to be searched first. */
+      pExpr->pLeft->flags |= EP_Collate;
+    }
+  }
   SWAP(Expr*,pExpr->pRight,pExpr->pLeft);
   if( pExpr->op>=TK_GT ){
     assert( TK_LT==TK_GT+2 );
@@ -104280,12 +103122,12 @@ static WhereTerm *findTerm(
           */
           assert(pX->pLeft);
           pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
-          assert(pColl || pParse->nErr);
+          if( pColl==0 ) pColl = pParse->db->pDfltColl;
   
           for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
             if( NEVER(j>=pIdx->nColumn) ) return 0;
           }
-          if( pColl && sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue;
+          if( sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue;
         }
         return pTerm;
       }
@@ -104803,7 +103645,7 @@ static void exprAnalyze(
   }
   pTerm = &pWC->a[idxTerm];
   pMaskSet = pWC->pMaskSet;
-  pExpr = pTerm->pExpr;
+  pExpr = sqlite3ExprSkipCollate(pTerm->pExpr);
   prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
   op = pExpr->op;
   if( op==TK_IN ){
@@ -104830,8 +103672,8 @@ static void exprAnalyze(
   pTerm->iParent = -1;
   pTerm->eOperator = 0;
   if( allowedOp(op) && (pTerm->prereqRight & prereqLeft)==0 ){
-    Expr *pLeft = pExpr->pLeft;
-    Expr *pRight = pExpr->pRight;
+    Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft);
+    Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
     if( pLeft->op==TK_COLUMN ){
       pTerm->leftCursor = pLeft->iTable;
       pTerm->u.leftColumn = pLeft->iColumn;
@@ -104859,7 +103701,7 @@ static void exprAnalyze(
         pNew = pTerm;
       }
       exprCommute(pParse, pDup);
-      pLeft = pDup->pLeft;
+      pLeft = sqlite3ExprSkipCollate(pDup->pLeft);
       pNew->leftCursor = pLeft->iTable;
       pNew->u.leftColumn = pLeft->iColumn;
       testcase( (prereqLeft | extraRight) != prereqLeft );
@@ -104938,7 +103780,7 @@ static void exprAnalyze(
     Expr *pNewExpr2;
     int idxNew1;
     int idxNew2;
-    CollSeq *pColl;    /* Collating sequence to use */
+    Token sCollSeqName;  /* Name of collating sequence */
 
     pLeft = pExpr->x.pList->a[1].pExpr;
     pStr2 = sqlite3ExprDup(db, pStr1, 0);
@@ -104960,16 +103802,19 @@ static void exprAnalyze(
       }
       *pC = c + 1;
     }
-    pColl = sqlite3FindCollSeq(db, SQLITE_UTF8, noCase ? "NOCASE" : "BINARY",0);
+    sCollSeqName.z = noCase ? "NOCASE" : "BINARY";
+    sCollSeqName.n = 6;
+    pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
     pNewExpr1 = sqlite3PExpr(pParse, TK_GE, 
-                     sqlite3ExprSetColl(sqlite3ExprDup(db,pLeft,0), pColl),
-                     pStr1, 0);
+           sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName),
+           pStr1, 0);
     idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
     testcase( idxNew1==0 );
     exprAnalyze(pSrc, pWC, idxNew1);
+    pNewExpr2 = sqlite3ExprDup(db, pLeft, 0);
     pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
-                     sqlite3ExprSetColl(sqlite3ExprDup(db,pLeft,0), pColl),
-                     pStr2, 0);
+           sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName),
+           pStr2, 0);
     idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
     testcase( idxNew2==0 );
     exprAnalyze(pSrc, pWC, idxNew2);
@@ -105066,25 +103911,6 @@ static void exprAnalyze(
   pTerm->prereqRight |= extraRight;
 }
 
-/*
-** Return TRUE if any of the expressions in pList->a[iFirst...] contain
-** a reference to any table other than the iBase table.
-*/
-static int referencesOtherTables(
-  ExprList *pList,          /* Search expressions in ths list */
-  WhereMaskSet *pMaskSet,   /* Mapping from tables to bitmaps */
-  int iFirst,               /* Be searching with the iFirst-th expression */
-  int iBase                 /* Ignore references to this table */
-){
-  Bitmask allowed = ~getMask(pMaskSet, iBase);
-  while( iFirst<pList->nExpr ){
-    if( (exprTableUsage(pMaskSet, pList->a[iFirst++].pExpr)&allowed)!=0 ){
-      return 1;
-    }
-  }
-  return 0;
-}
-
 /*
 ** 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
@@ -105106,12 +103932,12 @@ static int findIndexCol(
   const char *zColl = pIdx->azColl[iCol];
 
   for(i=0; i<pList->nExpr; i++){
-    Expr *p = pList->a[i].pExpr;
+    Expr *p = sqlite3ExprSkipCollate(pList->a[i].pExpr);
     if( p->op==TK_COLUMN
      && p->iColumn==pIdx->aiColumn[iCol]
      && p->iTable==iBase
     ){
-      CollSeq *pColl = sqlite3ExprCollSeq(pParse, p);
+      CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);
       if( ALWAYS(pColl) && 0==sqlite3StrICmp(pColl->zName, zColl) ){
         return i;
       }
@@ -105144,7 +103970,8 @@ static int isDistinctIndex(
   Bitmask mask = 0;               /* Mask of unaccounted for pDistinct exprs */
   int i;                          /* Iterator variable */
 
-  if( pIdx->zName==0 || pDistinct==0 || pDistinct->nExpr>=BMS ) return 0;
+  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
@@ -105157,7 +103984,7 @@ static int isDistinctIndex(
   */
   for(i=0; i<pDistinct->nExpr; i++){
     WhereTerm *pTerm;
-    Expr *p = pDistinct->a[i].pExpr;
+    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 ){
@@ -105209,7 +104036,7 @@ static int isDistinctRedundant(
   ** current SELECT is a correlated sub-query.
   */
   for(i=0; i<pDistinct->nExpr; i++){
-    Expr *p = pDistinct->a[i].pExpr;
+    Expr *p = sqlite3ExprSkipCollate(pDistinct->a[i].pExpr);
     if( p->op==TK_COLUMN && p->iTable==iBase && p->iColumn<0 ) return 1;
   }
 
@@ -105246,165 +104073,6 @@ static int isDistinctRedundant(
   return 0;
 }
 
-/*
-** This routine decides if pIdx can be used to satisfy the ORDER BY
-** clause.  If it can, it returns 1.  If pIdx cannot satisfy the
-** ORDER BY clause, this routine returns 0.
-**
-** pOrderBy is an ORDER BY clause from a SELECT statement.  pTab is the
-** left-most table in the FROM clause of that same SELECT statement and
-** the table has a cursor number of "base".  pIdx is an index on pTab.
-**
-** nEqCol is the number of columns of pIdx that are used as equality
-** constraints.  Any of these columns may be missing from the ORDER BY
-** clause and the match can still be a success.
-**
-** All terms of the ORDER BY that match against the index must be either
-** ASC or DESC.  (Terms of the ORDER BY clause past the end of a UNIQUE
-** index do not need to satisfy this constraint.)  The *pbRev value is
-** set to 1 if the ORDER BY clause is all DESC and it is set to 0 if
-** the ORDER BY clause is all ASC.
-*/
-static int isSortingIndex(
-  Parse *pParse,          /* Parsing context */
-  WhereMaskSet *pMaskSet, /* Mapping from table cursor numbers to bitmaps */
-  Index *pIdx,            /* The index we are testing */
-  int base,               /* Cursor number for the table to be sorted */
-  ExprList *pOrderBy,     /* The ORDER BY clause */
-  int nEqCol,             /* Number of index columns with == constraints */
-  int wsFlags,            /* Index usages flags */
-  int *pbRev              /* Set to 1 if ORDER BY is DESC */
-){
-  int i, j;                       /* Loop counters */
-  int sortOrder = 0;              /* XOR of index and ORDER BY sort direction */
-  int nTerm;                      /* Number of ORDER BY terms */
-  struct ExprList_item *pTerm;    /* A term of the ORDER BY clause */
-  sqlite3 *db = pParse->db;
-
-  if( !pOrderBy ) return 0;
-  if( wsFlags & WHERE_COLUMN_IN ) return 0;
-  if( pIdx->bUnordered ) return 0;
-
-  nTerm = pOrderBy->nExpr;
-  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.
-  */
-  for(i=j=0, pTerm=pOrderBy->a; j<nTerm && i<=pIdx->nColumn; i++){
-    Expr *pExpr;       /* The expression of the ORDER BY pTerm */
-    CollSeq *pColl;    /* The collating sequence of pExpr */
-    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 */
-    const char *zColl; /* Name of the collating sequence for i-th index term */
-
-    pExpr = pTerm->pExpr;
-    if( pExpr->op!=TK_COLUMN || pExpr->iTable!=base ){
-      /* Can not use an index sort on anything that is not a column in the
-      ** left-most table of the FROM clause */
-      break;
-    }
-    pColl = sqlite3ExprCollSeq(pParse, pExpr);
-    if( !pColl ){
-      pColl = db->pDfltColl;
-    }
-    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];
-    }else{
-      iColumn = -1;
-      iSortOrder = 0;
-      zColl = pColl->zName;
-    }
-    if( pExpr->iColumn!=iColumn || sqlite3StrICmp(pColl->zName, zColl) ){
-      /* Term j of the ORDER BY clause does not match column i of the index */
-      if( i<nEqCol ){
-        /* If an index column that is constrained by == fails to match an
-        ** ORDER BY term, that is OK.  Just ignore that column of the index
-        */
-        continue;
-      }else if( i==pIdx->nColumn ){
-        /* Index column i is the rowid.  All other terms match. */
-        break;
-      }else{
-        /* If an index column fails to match and is not constrained by ==
-        ** then the index cannot satisfy the ORDER BY constraint.
-        */
-        return 0;
-      }
-    }
-    assert( pIdx->aSortOrder!=0 || iColumn==-1 );
-    assert( pTerm->sortOrder==0 || pTerm->sortOrder==1 );
-    assert( iSortOrder==0 || iSortOrder==1 );
-    termSortOrder = iSortOrder ^ pTerm->sortOrder;
-    if( i>nEqCol ){
-      if( termSortOrder!=sortOrder ){
-        /* Indices can only be used if all ORDER BY terms past the
-        ** equality constraints are all either DESC or ASC. */
-        return 0;
-      }
-    }else{
-      sortOrder = termSortOrder;
-    }
-    j++;
-    pTerm++;
-    if( iColumn<0 && !referencesOtherTables(pOrderBy, pMaskSet, j, base) ){
-      /* If the indexed column is the primary key and everything matches
-      ** so far and none of the ORDER BY terms to the right reference other
-      ** tables in the join, then we are assured that the index can be used 
-      ** to sort because the primary key is unique and so none of the other
-      ** columns will make any difference
-      */
-      j = nTerm;
-    }
-  }
-
-  *pbRev = sortOrder!=0;
-  if( j>=nTerm ){
-    /* All terms of the ORDER BY clause are covered by this index so
-    ** this index can be used for sorting. */
-    return 1;
-  }
-  if( pIdx->onError!=OE_None && i==pIdx->nColumn
-      && (wsFlags & WHERE_COLUMN_NULL)==0
-      && !referencesOtherTables(pOrderBy, pMaskSet, j, base) 
-  ){
-    Column *aCol = pIdx->pTable->aCol;
-
-    /* All terms of this index match some prefix of the ORDER BY clause,
-    ** the index is UNIQUE, and no terms on the tail of the ORDER BY
-    ** refer to other tables in a join. So, assuming that the index entries
-    ** visited contain no NULL values, then this index delivers rows in
-    ** the required order.
-    **
-    ** It is not possible for any of the first nEqCol index fields to be
-    ** NULL (since the corresponding "=" operator in the WHERE clause would 
-    ** not be true). So if all remaining index columns have NOT NULL 
-    ** constaints attached to them, we can be confident that the visited
-    ** index entries are free of NULLs.  */
-    for(i=nEqCol; i<pIdx->nColumn; i++){
-      if( aCol[pIdx->aiColumn[i]].notNull==0 ) break;
-    }
-    return (i==pIdx->nColumn);
-  }
-  return 0;
-}
-
 /*
 ** Prepare a crude estimate of the logarithm of the input value.
 ** The results need not be exact.  This is only used for estimating
@@ -105469,9 +104137,7 @@ static void TRACE_IDX_OUTPUTS(sqlite3_index_info *p){
 /* 
 ** Required because bestIndex() is called by bestOrClauseIndex() 
 */
-static void bestIndex(
-    Parse*, WhereClause*, struct SrcList_item*,
-    Bitmask, Bitmask, ExprList*, WhereCost*);
+static void bestIndex(WhereBestIdx*);
 
 /*
 ** This routine attempts to find an scanning strategy that can be used 
@@ -105480,20 +104146,14 @@ static void bestIndex(
 ** The table associated with FROM clause term pSrc may be either a
 ** regular B-Tree table or a virtual table.
 */
-static void bestOrClauseIndex(
-  Parse *pParse,              /* The parsing context */
-  WhereClause *pWC,           /* The WHERE clause */
-  struct SrcList_item *pSrc,  /* The FROM clause term to search */
-  Bitmask notReady,           /* Mask of cursors not available for indexing */
-  Bitmask notValid,           /* Cursors not available for any purpose */
-  ExprList *pOrderBy,         /* The ORDER BY clause */
-  WhereCost *pCost            /* Lowest cost query plan */
-){
+static void bestOrClauseIndex(WhereBestIdx *p){
 #ifndef SQLITE_OMIT_OR_OPTIMIZATION
-  const int iCur = pSrc->iCursor;   /* The cursor of the table to be accessed */
+  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 */
+  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. */
@@ -105507,7 +104167,7 @@ static void bestOrClauseIndex(
   /* Search the WHERE clause terms for a usable WO_OR term. */
   for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
     if( pTerm->eOperator==WO_OR 
-     && ((pTerm->prereqAll & ~maskSrc) & notReady)==0
+     && ((pTerm->prereqAll & ~maskSrc) & p->notReady)==0
      && (pTerm->u.pOrInfo->indexable & maskSrc)!=0 
     ){
       WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc;
@@ -105517,15 +104177,19 @@ static void bestOrClauseIndex(
       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++){
-        WhereCost sTermCost;
         WHERETRACE(("... Multi-index OR testing for term %d of %d....\n", 
           (pOrTerm - pOrWC->a), (pTerm - pWC->a)
         ));
         if( pOrTerm->eOperator==WO_AND ){
-          WhereClause *pAndWC = &pOrTerm->u.pAndInfo->wc;
-          bestIndex(pParse, pAndWC, pSrc, notReady, notValid, 0, &sTermCost);
+          sBOI.pWC = &pOrTerm->u.pAndInfo->wc;
+          bestIndex(&sBOI);
         }else if( pOrTerm->leftCursor==iCur ){
           WhereClause tempWC;
           tempWC.pParse = pWC->pParse;
@@ -105535,19 +104199,20 @@ static void bestOrClauseIndex(
           tempWC.a = pOrTerm;
           tempWC.wctrlFlags = 0;
           tempWC.nTerm = 1;
-          bestIndex(pParse, &tempWC, pSrc, notReady, notValid, 0, &sTermCost);
+          sBOI.pWC = &tempWC;
+          bestIndex(&sBOI);
         }else{
           continue;
         }
-        rTotal += sTermCost.rCost;
-        nRow += sTermCost.plan.nRow;
-        used |= sTermCost.used;
-        if( rTotal>=pCost->rCost ) break;
+        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( pOrderBy!=0 ){
+      if( p->pOrderBy!=0 ){
         WHERETRACE(("... sorting increases OR cost %.9g to %.9g\n",
                     rTotal, rTotal+nRow*estLog(nRow)));
         rTotal += nRow*estLog(nRow);
@@ -105557,12 +104222,13 @@ static void bestOrClauseIndex(
       ** 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<pCost->rCost ){
-        pCost->rCost = rTotal;
-        pCost->used = used;
-        pCost->plan.nRow = nRow;
-        pCost->plan.wsFlags = flags;
-        pCost->plan.u.pTerm = pTerm;
+      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;
       }
     }
   }
@@ -105599,15 +104265,12 @@ static int termCanDriveIndex(
 ** is taken into account, then alter the query plan to use the
 ** transient index.
 */
-static void bestAutomaticIndex(
-  Parse *pParse,              /* The parsing context */
-  WhereClause *pWC,           /* The WHERE clause */
-  struct SrcList_item *pSrc,  /* The FROM clause term to search */
-  Bitmask notReady,           /* Mask of cursors that are not available */
-  WhereCost *pCost            /* Lowest cost query plan */
-){
-  double nTableRow;           /* Rows in the input table */
-  double logN;                /* log(nTableRow) */
+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[] */
@@ -105621,10 +104284,16 @@ static void bestAutomaticIndex(
     /* Automatic indices are disabled at run-time */
     return;
   }
-  if( (pCost->plan.wsFlags & WHERE_NOT_FULLSCAN)!=0 ){
+  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;
@@ -105639,7 +104308,7 @@ static void bestAutomaticIndex(
   nTableRow = pTable->nRowEst;
   logN = estLog(nTableRow);
   costTempIdx = 2*logN*(nTableRow/pParse->nQueryLoop + 1);
-  if( costTempIdx>=pCost->rCost ){
+  if( costTempIdx>=p->cost.rCost ){
     /* The cost of creating the transient table would be greater than
     ** doing the full table scan */
     return;
@@ -105648,19 +104317,19 @@ static void bestAutomaticIndex(
   /* Search for any equality comparison term */
   pWCEnd = &pWC->a[pWC->nTerm];
   for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
-    if( termCanDriveIndex(pTerm, pSrc, notReady) ){
+    if( termCanDriveIndex(pTerm, pSrc, p->notReady) ){
       WHERETRACE(("auto-index reduces cost from %.1f to %.1f\n",
-                    pCost->rCost, costTempIdx));
-      pCost->rCost = costTempIdx;
-      pCost->plan.nRow = logN + 1;
-      pCost->plan.wsFlags = WHERE_TEMP_INDEX;
-      pCost->used = pTerm->prereqRight;
+                    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,B,C,D,E)  /* no-op */
+# define bestAutomaticIndex(A)  /* no-op */
 #endif /* SQLITE_OMIT_AUTOMATIC_INDEX */
 
 
@@ -105821,12 +104490,11 @@ 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(
-  Parse *pParse, 
-  WhereClause *pWC,
-  struct SrcList_item *pSrc,
-  ExprList *pOrderBy
-){
+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;
   int i, j;
   int nTerm;
   struct sqlite3_index_constraint *pIdxCons;
@@ -105856,12 +104524,13 @@ static sqlite3_index_info *allocateIndexInfo(
   */
   nOrderBy = 0;
   if( pOrderBy ){
-    for(i=0; i<pOrderBy->nExpr; i++){
+    int n = pOrderBy->nExpr;
+    for(i=0; i<n; i++){
       Expr *pExpr = pOrderBy->a[i].pExpr;
       if( pExpr->op!=TK_COLUMN || pExpr->iTable!=pSrc->iCursor ) break;
     }
-    if( i==pOrderBy->nExpr ){
-      nOrderBy = pOrderBy->nExpr;
+    if( i==n){
+      nOrderBy = n;
     }
   }
 
@@ -105985,16 +104654,10 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
 ** routine takes care of freeing the sqlite3_index_info structure after
 ** everybody has finished with it.
 */
-static void bestVirtualIndex(
-  Parse *pParse,                  /* The parsing context */
-  WhereClause *pWC,               /* The WHERE clause */
-  struct SrcList_item *pSrc,      /* The FROM clause term to search */
-  Bitmask notReady,               /* Mask of cursors not available for index */
-  Bitmask notValid,               /* Cursors not valid for any purpose */
-  ExprList *pOrderBy,             /* The order by clause */
-  WhereCost *pCost,               /* Lowest cost query plan */
-  sqlite3_index_info **ppIdxInfo  /* Index information passed to xBestIndex */
-){
+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;
@@ -106008,15 +104671,15 @@ static void bestVirtualIndex(
   ** malloc in allocateIndexInfo() fails and this function returns leaving
   ** wsFlags in an uninitialized state, the caller may behave unpredictably.
   */
-  memset(pCost, 0, sizeof(*pCost));
-  pCost->plan.wsFlags = WHERE_VIRTUALTABLE;
+  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 = *ppIdxInfo;
+  pIdxInfo = *p->ppIdxInfo;
   if( pIdxInfo==0 ){
-    *ppIdxInfo = pIdxInfo = allocateIndexInfo(pParse, pWC, pSrc, pOrderBy);
+    *p->ppIdxInfo = pIdxInfo = allocateIndexInfo(p);
   }
   if( pIdxInfo==0 ){
     return;
@@ -106061,7 +104724,7 @@ static void bestVirtualIndex(
   for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
     j = pIdxCons->iTermOffset;
     pTerm = &pWC->a[j];
-    pIdxCons->usable = (pTerm->prereqRight&notReady) ? 0 : 1;
+    pIdxCons->usable = (pTerm->prereqRight&p->notReady) ? 0 : 1;
   }
   memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
   if( pIdxInfo->needToFreeIdxStr ){
@@ -106074,7 +104737,7 @@ static void bestVirtualIndex(
   /* ((double)2) In case of SQLITE_OMIT_FLOATING_POINT... */
   pIdxInfo->estimatedCost = SQLITE_BIG_DBL / ((double)2);
   nOrderBy = pIdxInfo->nOrderBy;
-  if( !pOrderBy ){
+  if( !p->pOrderBy ){
     pIdxInfo->nOrderBy = 0;
   }
 
@@ -106085,7 +104748,7 @@ static void bestVirtualIndex(
   pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
   for(i=0; i<pIdxInfo->nConstraint; i++){
     if( pUsage[i].argvIndex>0 ){
-      pCost->used |= pWC->a[pIdxCons[i].iTermOffset].prereqRight;
+      p->cost.used |= pWC->a[pIdxCons[i].iTermOffset].prereqRight;
     }
   }
 
@@ -106094,7 +104757,7 @@ static void bestVirtualIndex(
   ** matches the processing for non-virtual tables in bestBtreeIndex().
   */
   rCost = pIdxInfo->estimatedCost;
-  if( pOrderBy && pIdxInfo->orderByConsumed==0 ){
+  if( p->pOrderBy && pIdxInfo->orderByConsumed==0 ){
     rCost += estLog(rCost)*rCost;
   }
 
@@ -106106,21 +104769,24 @@ static void bestVirtualIndex(
   ** is defined.
   */
   if( (SQLITE_BIG_DBL/((double)2))<rCost ){
-    pCost->rCost = (SQLITE_BIG_DBL/((double)2));
+    p->cost.rCost = (SQLITE_BIG_DBL/((double)2));
   }else{
-    pCost->rCost = rCost;
+    p->cost.rCost = rCost;
   }
-  pCost->plan.u.pVtabIdx = pIdxInfo;
+  p->cost.plan.u.pVtabIdx = pIdxInfo;
   if( pIdxInfo->orderByConsumed ){
-    pCost->plan.wsFlags |= WHERE_ORDERBY;
+    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;
   }
-  pCost->plan.nEq = 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(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost);
+  bestOrClauseIndex(p);
 }
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
 
@@ -106208,10 +104874,8 @@ static int whereKeyStats(
         pColl = db->pDfltColl;
         assert( pColl->enc==SQLITE_UTF8 );
       }else{
-        pColl = sqlite3GetCollSeq(db, SQLITE_UTF8, 0, *pIdx->azColl);
+        pColl = sqlite3GetCollSeq(pParse, SQLITE_UTF8, 0, *pIdx->azColl);
         if( pColl==0 ){
-          sqlite3ErrorMsg(pParse, "no such collation sequence: %s",
-                          *pIdx->azColl);
           return SQLITE_ERROR;
         }
         z = (const u8 *)sqlite3ValueText(pVal, pColl->enc);
@@ -106519,11 +105183,275 @@ static int whereInScanEst(
 }
 #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 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 */
+
+  if( p->i==0 ){
+    nPriorSat = 0;
+  }else{
+    nPriorSat = p->aLevel[p->i-1].plan.nOBSat;
+    if( (p->aLevel[p->i-1].plan.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;
+    }
+  }
+  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 ){
+      /* Constraints of the form: "X IN ..." cannot be used with an ORDER BY
+      ** because we do not know in what order the values on the RHS of the IN
+      ** operator will occur. */
+      break;
+    }else if( pConstraint->eOperator==WO_ISNULL ){
+      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 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;
+
+  /* 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( seenRowid || (uniqueNotNull && i>=pIdx->nColumn) ){
+    /* 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 WhereCost object supplied as the
-** last parameter.
+** 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.
@@ -106543,21 +105471,15 @@ static int whereInScanEst(
 ** 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 (pSrc->notIndexed!=0) was attached to the table 
+** 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(
-  Parse *pParse,              /* The parsing context */
-  WhereClause *pWC,           /* The WHERE clause */
-  struct SrcList_item *pSrc,  /* The FROM clause term to search */
-  Bitmask notReady,           /* Mask of cursors not available for indexing */
-  Bitmask notValid,           /* Cursors not available for any purpose */
-  ExprList *pOrderBy,         /* The ORDER BY clause */
-  ExprList *pDistinct,        /* The select-list if query is DISTINCT */
-  WhereCost *pCost            /* Lowest cost query plan */
-){
+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 */
@@ -106566,11 +105488,16 @@ static void bestBtreeIndex(
   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 pCost->plan.wsFlag */
+  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(pCost, 0, sizeof(*pCost));
-  pCost->rCost = SQLITE_BIG_DBL;
+  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
@@ -106616,22 +105543,29 @@ static void bestBtreeIndex(
     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;
-    double cost;                /* Cost of using pProbe */
-    double nRow;                /* Estimated number of rows in result set */
+    WhereCost pc;               /* Cost of using pProbe */
     double log10N = (double)1;  /* base-10 logarithm of nRow (inexact) */
-    int rev;                    /* True to scan in reverse order */
-    int wsFlags = 0;
-    Bitmask used = 0;
 
     /* 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.
     **
-    **  nEq: 
+    **  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.
@@ -106674,6 +105608,10 @@ static void bestBtreeIndex(
     **    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.
@@ -106689,29 +105627,35 @@ static void bestBtreeIndex(
     **             SELECT a, b    FROM tbl WHERE a = 1;
     **             SELECT a, b, c FROM tbl WHERE a = 1;
     */
-    int nEq;                      /* Number of == or IN terms matching index */
     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 */
-    int bSort = !!pOrderBy;       /* True if external sort required */
-    int bDist = !!pDistinct;      /* True if index cannot help with DISTINCT */
-    int bLookup = 0;              /* True if not a covering index */
+    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
 
-    /* Determine the values of nEq and nInMul */
-    for(nEq=0; nEq<pProbe->nColumn; nEq++){
-      int j = pProbe->aiColumn[nEq];
-      pTerm = findTerm(pWC, iCur, j, notReady, eqTermMask, pIdx);
+    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;
-      wsFlags |= (WHERE_COLUMN_EQ|WHERE_ROWID_EQ);
+      pc.plan.wsFlags |= (WHERE_COLUMN_EQ|WHERE_ROWID_EQ);
       testcase( pTerm->pWC!=pWC );
       if( pTerm->eOperator & WO_IN ){
         Expr *pExpr = pTerm->pExpr;
-        wsFlags |= WHERE_COLUMN_IN;
+        pc.plan.wsFlags |= WHERE_COLUMN_IN;
         if( ExprHasProperty(pExpr, EP_xIsSelect) ){
           /* "x IN (SELECT ...)":  Assume the SELECT returns 25 rows */
           nInMul *= 25;
@@ -106721,12 +105665,12 @@ static void bestBtreeIndex(
           nInMul *= pExpr->x.pList->nExpr;
         }
       }else if( pTerm->eOperator & WO_ISNULL ){
-        wsFlags |= WHERE_COLUMN_NULL;
+        pc.plan.wsFlags |= WHERE_COLUMN_NULL;
       }
 #ifdef SQLITE_ENABLE_STAT3
-      if( nEq==0 && pProbe->aSample ) pFirstTerm = pTerm;
+      if( pc.plan.nEq==0 && pProbe->aSample ) pFirstTerm = pTerm;
 #endif
-      used |= pTerm->prereqRight;
+      pc.used |= pTerm->prereqRight;
     }
  
     /* If the index being considered is UNIQUE, and there is an equality 
@@ -106735,65 +105679,80 @@ static void bestBtreeIndex(
     ** 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 (nEq+1) that can be 
+    ** there is a range constraint on indexed column (pc.plan.nEq+1) that can be 
     ** optimized using the index. 
     */
-    if( nEq==pProbe->nColumn && pProbe->onError!=OE_None ){
-      testcase( wsFlags & WHERE_COLUMN_IN );
-      testcase( wsFlags & WHERE_COLUMN_NULL );
-      if( (wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 ){
-        wsFlags |= WHERE_UNIQUE;
+    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 = (nEq==pProbe->nColumn ? -1 : pProbe->aiColumn[nEq]);
-      if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){
-        WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pIdx);
-        WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pIdx);
-        whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &rangeDiv);
+      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;
-          wsFlags |= WHERE_TOP_LIMIT;
-          used |= pTop->prereqRight;
+          pc.plan.wsFlags |= WHERE_TOP_LIMIT;
+          pc.used |= pTop->prereqRight;
           testcase( pTop->pWC!=pWC );
         }
         if( pBtm ){
           nBound++;
-          wsFlags |= WHERE_BTM_LIMIT;
-          used |= pBtm->prereqRight;
+          pc.plan.wsFlags |= WHERE_BTM_LIMIT;
+          pc.used |= pBtm->prereqRight;
           testcase( pBtm->pWC!=pWC );
         }
-        wsFlags |= (WHERE_COLUMN_RANGE|WHERE_ROWID_RANGE);
+        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 wsFlags. Otherwise, if there is an ORDER BY clause but the index
-    ** will scan rows in a different order, set the bSort variable.  */
-    if( isSortingIndex(
-          pParse, pWC->pMaskSet, pProbe, iCur, pOrderBy, nEq, wsFlags, &rev)
-    ){
-      bSort = 0;
-      wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY;
-      wsFlags |= (rev ? WHERE_REVERSE : 0);
+    ** 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;
+      WHERETRACE(("      --> before isSortingIndex: nPriorSat=%d\n",nPriorSat));
+      pc.plan.nOBSat = isSortingIndex(p, pProbe, iCur, &bRev);
+      WHERETRACE(("      --> after  isSortingIndex: bRev=%d nOBSat=%d\n",
+                  bRev, pc.plan.nOBSat));
+      if( nPriorSat<pc.plan.nOBSat || (pc.plan.wsFlags & WHERE_UNIQUE)!=0 ){
+        pc.plan.wsFlags |= WHERE_ORDERED;
+      }
+      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 wsFlags. */
-    if( isDistinctIndex(pParse, pWC, pProbe, iCur, pDistinct, nEq)
-     && (wsFlags & WHERE_COLUMN_IN)==0
+    ** 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;
-      wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_DISTINCT;
+      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
-    ** wsFlags. Otherwise, set the bLookup variable to true.  */
-    if( pIdx && wsFlags ){
+    ** 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++){
@@ -106803,7 +105762,7 @@ static void bestBtreeIndex(
         }
       }
       if( m==0 ){
-        wsFlags |= WHERE_IDX_ONLY;
+        pc.plan.wsFlags |= WHERE_IDX_ONLY;
       }else{
         bLookup = 1;
       }
@@ -106813,10 +105772,10 @@ static void bestBtreeIndex(
     ** 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.
     */
-    nRow = (double)(aiRowEst[nEq] * nInMul);
-    if( bInEst && nRow*2>aiRowEst[0] ){
-      nRow = aiRowEst[0]/2;
-      nInMul = (int)(nRow / aiRowEst[nEq]);
+    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
@@ -106826,15 +105785,18 @@ static void bestBtreeIndex(
     ** to get a better estimate on the number of rows based on
     ** VALUE and how common that value is according to the histogram.
     */
-    if( nRow>(double)1 && nEq==1 && pFirstTerm!=0 && aiRowEst[1]>1 ){
+    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_ISNULL );
-        whereEqualScanEst(pParse, pProbe, pFirstTerm->pExpr->pRight, &nRow);
+        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, &nRow);
+        whereInScanEst(pParse, pProbe, pFirstTerm->pExpr->x.pList,
+                       &pc.plan.nRow);
       }
     }
 #endif /* SQLITE_ENABLE_STAT3 */
@@ -106842,8 +105804,8 @@ static void bestBtreeIndex(
     /* Adjust the number of output rows and downward to reflect rows
     ** that are excluded by range constraints.
     */
-    nRow = nRow/rangeDiv;
-    if( nRow<1 ) nRow = 1;
+    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
@@ -106858,7 +105820,18 @@ static void bestBtreeIndex(
     ** So this computation assumes table records are about twice as big
     ** as index records
     */
-    if( (wsFlags & WHERE_NOT_FULLSCAN)==0 ){
+    if( (pc.plan.wsFlags&~(WHERE_REVERSE|WHERE_ORDERED))==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.
       **
@@ -106868,10 +105841,15 @@ static void bestBtreeIndex(
       ** decision and one which we expect to revisit in the future.  But
       ** it seems to be working well enough at the moment.
       */
-      cost = aiRowEst[0]*4;
+      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]);
-      cost = nRow;
+      pc.rCost = pc.plan.nRow;
       if( pIdx ){
         if( bLookup ){
           /* For an index lookup followed by a table lookup:
@@ -106879,20 +105857,20 @@ static void bestBtreeIndex(
           **  + nRow steps through the index
           **  + nRow table searches to lookup the table entry using the rowid
           */
-          cost += (nInMul + nRow)*log10N;
+          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
           */
-          cost += nInMul*log10N;
+          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
         */
-        cost += nInMul*log10N;
+        pc.rCost += nInMul*log10N;
       }
     }
 
@@ -106903,10 +105881,12 @@ static void bestBtreeIndex(
     ** difference and select C of 3.0.
     */
     if( bSort ){
-      cost += nRow*estLog(nRow)*3;
+      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 ){
-      cost += nRow*estLog(nRow)*3;
+      pc.rCost += pc.plan.nRow*estLog(pc.plan.nRow)*3;
     }
 
     /**** Cost of using this index has now been computed ****/
@@ -106927,25 +105907,25 @@ static void bestBtreeIndex(
     ** might be selected even when there exists an optimal index that has
     ** no such dependency.
     */
-    if( nRow>2 && cost<=pCost->rCost ){
+    if( pc.plan.nRow>2 && pc.rCost<=p->cost.rCost ){
       int k;                       /* Loop counter */
-      int nSkipEq = nEq;           /* Number of == constraints to skip */
+      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; nRow>2 && k; k--, pTerm++){
+      for(pTerm=pWC->a, k=pWC->nTerm; pc.plan.nRow>2 && k; k--, pTerm++){
         if( pTerm->wtFlags & TERM_VIRTUAL ) continue;
-        if( (pTerm->prereqAll & notValid)!=thisTab ) continue;
+        if( (pTerm->prereqAll & p->notValid)!=thisTab ) continue;
         if( pTerm->eOperator & (WO_EQ|WO_IN|WO_ISNULL) ){
           if( nSkipEq ){
-            /* Ignore the first nEq equality matches since the index
+            /* 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 */
-            nRow /= 10;
+            pc.plan.nRow /= 10;
           }
         }else if( pTerm->eOperator & (WO_LT|WO_LE|WO_GT|WO_GE) ){
           if( nSkipRange ){
@@ -106959,37 +105939,33 @@ static void bestBtreeIndex(
             ** more selective intentionally because of the subjective 
             ** observation that indexed range constraints really are more
             ** selective in practice, on average. */
-            nRow /= 3;
+            pc.plan.nRow /= 3;
           }
         }else if( pTerm->eOperator!=WO_NOOP ){
           /* Any other expression lowers the output row count by half */
-          nRow /= 2;
+          pc.plan.nRow /= 2;
         }
       }
-      if( nRow<2 ) nRow = 2;
+      if( pc.plan.nRow<2 ) pc.plan.nRow = 2;
     }
 
 
     WHERETRACE((
-      "%s(%s): nEq=%d nInMul=%d rangeDiv=%d bSort=%d bLookup=%d wsFlags=0x%x\n"
-      "         notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f used=0x%llx\n",
-      pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk"), 
-      nEq, nInMul, (int)rangeDiv, bSort, bLookup, wsFlags,
-      notReady, log10N, nRow, cost, used
+      "      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 pCost structure.
+    ** index and its cost in the p->cost structure.
     */
-    if( (!pIdx || wsFlags)
-     && (cost<pCost->rCost || (cost<=pCost->rCost && nRow<pCost->plan.nRow))
-    ){
-      pCost->rCost = cost;
-      pCost->used = used;
-      pCost->plan.nRow = nRow;
-      pCost->plan.wsFlags = (wsFlags&wsFlagMask);
-      pCost->plan.nEq = nEq;
-      pCost->plan.u.pIdx = pIdx;
+    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
@@ -107006,25 +105982,23 @@ static void bestBtreeIndex(
   ** in. This is used for application testing, to help find cases
   ** where application behaviour depends on the (undefined) order that
   ** SQLite outputs rows in in the absence of an ORDER BY clause.  */
-  if( !pOrderBy && pParse->db->flags & SQLITE_ReverseOrder ){
-    pCost->plan.wsFlags |= WHERE_REVERSE;
+  if( !p->pOrderBy && pParse->db->flags & SQLITE_ReverseOrder ){
+    p->cost.plan.wsFlags |= WHERE_REVERSE;
   }
 
-  assert( pOrderBy || (pCost->plan.wsFlags&WHERE_ORDERBY)==0 );
-  assert( pCost->plan.u.pIdx==0 || (pCost->plan.wsFlags&WHERE_ROWID_EQ)==0 );
+  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 
-       || pCost->plan.u.pIdx==0 
-       || pCost->plan.u.pIdx==pSrc->pIndex 
+       || p->cost.plan.u.pIdx==0 
+       || p->cost.plan.u.pIdx==pSrc->pIndex 
   );
 
-  WHERETRACE(("best index is: %s\n", 
-    ((pCost->plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ? "none" : 
-         pCost->plan.u.pIdx ? pCost->plan.u.pIdx->zName : "ipk")
-  ));
+  WHERETRACE(("   best index is: %s\n",
+         p->cost.plan.u.pIdx ? p->cost.plan.u.pIdx->zName : "ipk"));
   
-  bestOrClauseIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost);
-  bestAutomaticIndex(pParse, pWC, pSrc, notReady, pCost);
-  pCost->plan.wsFlags |= eqTermMask;
+  bestOrClauseIndex(p);
+  bestAutomaticIndex(p);
+  p->cost.plan.wsFlags |= eqTermMask;
 }
 
 /*
@@ -107032,28 +106006,27 @@ static void bestBtreeIndex(
 ** 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(
-  Parse *pParse,              /* The parsing context */
-  WhereClause *pWC,           /* The WHERE clause */
-  struct SrcList_item *pSrc,  /* The FROM clause term to search */
-  Bitmask notReady,           /* Mask of cursors not available for indexing */
-  Bitmask notValid,           /* Cursors not available for any purpose */
-  ExprList *pOrderBy,         /* The ORDER BY clause */
-  WhereCost *pCost            /* Lowest cost query plan */
-){
+static void bestIndex(WhereBestIdx *p){
 #ifndef SQLITE_OMIT_VIRTUALTABLE
-  if( IsVirtual(pSrc->pTab) ){
-    sqlite3_index_info *p = 0;
-    bestVirtualIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost,&p);
-    if( p->needToFreeIdxStr ){
-      sqlite3_free(p->idxStr);
-    }
-    sqlite3DbFree(pParse->db, p);
+  if( IsVirtual(p->pSrc->pTab) ){
+    sqlite3_index_info *pIdxInfo = 0;
+    p->ppIdxInfo = &pIdxInfo;
+    bestVirtualIndex(p);
+    if( pIdxInfo->needToFreeIdxStr ){
+      sqlite3_free(pIdxInfo->idxStr);
+    }
+    sqlite3DbFree(p->pParse->db, pIdxInfo);
   }else
 #endif
   {
-    bestBtreeIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, 0, pCost);
+    bestBtreeIndex(p);
   }
 }
 
@@ -107282,7 +106255,7 @@ static int codeAllEqualityTerms(
     int r1;
     int k = pIdx->aiColumn[j];
     pTerm = findTerm(pWC, iCur, k, notReady, pLevel->plan.wsFlags, pIdx);
-    if( NEVER(pTerm==0) ) break;
+    if( pTerm==0 ) break;
     /* 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 );
@@ -107531,6 +106504,16 @@ static Bitmask codeOneLoopStart(
     VdbeComment((v, "init LEFT JOIN no-match flag"));
   }
 
+  /* Special case of a FROM clause subquery implemented as a co-routine */
+  if( pTabItem->viaCoroutine ){
+    int regYield = pTabItem->regReturn;
+    sqlite3VdbeAddOp2(v, OP_Integer, pTabItem->addrFillSub-1, regYield);
+    pLevel->p2 =  sqlite3VdbeAddOp1(v, OP_Yield, regYield);
+    VdbeComment((v, "next row of co-routine %s", pTabItem->pTab->zName));
+    sqlite3VdbeAddOp2(v, OP_If, regYield+1, addrBrk);
+    pLevel->op = OP_Goto;
+  }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
@@ -107749,7 +106732,7 @@ static Bitmask codeOneLoopStart(
     ** this requires some special handling.
     */
     if( (wctrlFlags&WHERE_ORDERBY_MIN)!=0
-     && (pLevel->plan.wsFlags&WHERE_ORDERBY)
+     && (pLevel->plan.wsFlags&WHERE_ORDERED)
      && (pIdx->nColumn>nEq)
     ){
       /* assert( pOrderBy->nExpr==1 ); */
@@ -107912,6 +106895,11 @@ static Bitmask codeOneLoopStart(
       pLevel->op = OP_Next;
     }
     pLevel->p1 = iIdxCur;
+    if( pLevel->plan.wsFlags & WHERE_COVER_SCAN ){
+      pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
+    }else{
+      assert( pLevel->p5==0 );
+    }
   }else
 
 #ifndef SQLITE_OMIT_OR_OPTIMIZATION
@@ -107957,6 +106945,8 @@ static Bitmask codeOneLoopStart(
     */
     WhereClause *pOrWc;    /* The OR-clause broken out into subterms */
     SrcList *pOrTab;       /* Shortened table list or OR-clause generation */
+    Index *pCov = 0;             /* Potential covering index (or NULL) */
+    int iCovCur = pParse->nTab++;  /* Cursor used for index scans (if any) */
 
     int regReturn = ++pParse->nMem;           /* Register used with OP_Gosub */
     int regRowset = 0;                        /* Register for RowSet object */
@@ -107975,7 +106965,7 @@ static Bitmask codeOneLoopStart(
     pLevel->op = OP_Return;
     pLevel->p1 = regReturn;
 
-    /* Set up a new SrcList ni pOrTab containing the table being scanned
+    /* Set up a new SrcList in pOrTab containing the table being scanned
     ** by this loop in the a[0] slot and all notReady tables in a[1..] slots.
     ** This becomes the SrcList in the recursive call to sqlite3WhereBegin().
     */
@@ -108052,8 +107042,10 @@ static Bitmask codeOneLoopStart(
         /* Loop through table entries that match term pOrTerm. */
         pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
                         WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY |
-                        WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY);
+                        WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY, iCovCur);
+        assert( pSubWInfo || pParse->nErr || pParse->db->mallocFailed );
         if( pSubWInfo ){
+          WhereLevel *pLvl;
           explainOneScan(
               pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
           );
@@ -108074,11 +107066,36 @@ static Bitmask codeOneLoopStart(
           */
           if( pSubWInfo->untestedTerms ) untestedTerms = 1;
 
+          /* If all of the OR-connected terms are optimized using the same
+          ** index, and the index is opened using the same cursor number
+          ** by each call to sqlite3WhereBegin() made by this loop, it may
+          ** be possible to use that index as a covering index.
+          **
+          ** If the call to sqlite3WhereBegin() above resulted in a scan that
+          ** uses an index, and this is either the first OR-connected term
+          ** processed or the index is the same as that used by all previous
+          ** terms, set pCov to the candidate covering index. Otherwise, set 
+          ** 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)
+          ){
+            assert( pLvl->iIdxCur==iCovCur );
+            pCov = pLvl->plan.u.pIdx;
+          }else{
+            pCov = 0;
+          }
+
           /* Finish the loop through table entries that match term pOrTerm. */
           sqlite3WhereEnd(pSubWInfo);
         }
       }
     }
+    pLevel->u.pCovidx = pCov;
+    if( pCov ) pLevel->iIdxCur = iCovCur;
     if( pAndExpr ){
       pAndExpr->pLeft = 0;
       sqlite3ExprDelete(pParse->db, pAndExpr);
@@ -108277,41 +107294,46 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
 **
 ** ORDER BY CLAUSE PROCESSING
 **
-** *ppOrderBy is a pointer to the ORDER BY clause of a SELECT statement,
+** pOrderBy is a pointer to the ORDER BY clause 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 ppOrderBy is NULL.
+** 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
-** *ppOrderBy is set to NULL.  This is an optimization that prevents an
-** unnecessary sort of the result set if an index appropriate for the
-** ORDER BY clause already exists.
+** 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 the *ppOrderBy is unchanged.
+** 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 */
   Expr *pWhere,         /* The WHERE clause */
-  ExprList **ppOrderBy, /* An ORDER BY clause, or NULL */
+  ExprList *pOrderBy,   /* An ORDER BY clause, or NULL */
   ExprList *pDistinct,  /* The select-list for DISTINCT queries - or NULL */
-  u16 wctrlFlags        /* One of the WHERE_* flags defined in sqliteInt.h */
+  u16 wctrlFlags,       /* One of the WHERE_* flags defined in sqliteInt.h */
+  int iIdxCur           /* If WHERE_ONETABLE_ONLY is set, index cursor number */
 ){
-  int i;                     /* Loop counter */
   int nByteWInfo;            /* Num. bytes allocated for WhereInfo struct */
   int nTabList;              /* Number of elements in pTabList */
   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 */
   WhereMaskSet *pMaskSet;    /* The expression mask set */
-  WhereClause *pWC;               /* Decomposition of the WHERE clause */
-  struct SrcList_item *pTabItem;  /* A single entry from pTabList */
-  WhereLevel *pLevel;             /* A single level in the pWInfo list */
-  int iFrom;                      /* First unused FROM clause element */
+  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 */
+  int ii;                    /* Loop counter */
   sqlite3 *db;               /* Database connection */
 
+
+  /* Variable initialization */
+  memset(&sWBI, 0, sizeof(sWBI));
+  sWBI.pParse = pParse;
+
   /* The number of tables in the FROM clause is limited by the number of
   ** bits in a Bitmask 
   */
@@ -108351,22 +107373,23 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
   pWInfo->pParse = pParse;
   pWInfo->pTabList = pTabList;
   pWInfo->iBreak = sqlite3VdbeMakeLabel(v);
-  pWInfo->pWC = pWC = (WhereClause *)&((u8 *)pWInfo)[nByteWInfo];
+  pWInfo->pWC = sWBI.pWC = (WhereClause *)&((u8 *)pWInfo)[nByteWInfo];
   pWInfo->wctrlFlags = wctrlFlags;
   pWInfo->savedNQueryLoop = pParse->nQueryLoop;
-  pMaskSet = (WhereMaskSet*)&pWC[1];
+  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( db->flags & SQLITE_DistinctOpt ) pDistinct = 0;
+  if( OptimizationDisabled(db, SQLITE_DistinctOpt) ) pDistinct = 0;
 
   /* Split the WHERE clause into separate subexpressions where each
   ** subexpression is separated by an AND operator.
   */
   initMaskSet(pMaskSet);
-  whereClauseInit(pWC, pParse, pMaskSet, wctrlFlags);
+  whereClauseInit(sWBI.pWC, pParse, pMaskSet, wctrlFlags);
   sqlite3ExprCodeConstants(pParse, pWhere);
-  whereSplit(pWC, pWhere, TK_AND);   /* IMP: R-15842-53296 */
+  whereSplit(sWBI.pWC, pWhere, TK_AND);   /* IMP: R-15842-53296 */
     
   /* Special case: a WHERE clause that is constant.  Evaluate the
   ** expression and either jump over all of the code or fall thru.
@@ -108397,20 +107420,20 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
   ** equal to pTabList->nSrc but might be shortened to 1 if the
   ** WHERE_ONETABLE_ONLY flag is set.
   */
-  assert( pWC->vmask==0 && pMaskSet->n==0 );
-  for(i=0; i<pTabList->nSrc; i++){
-    createMask(pMaskSet, pTabList->a[i].iCursor);
+  assert( sWBI.pWC->vmask==0 && pMaskSet->n==0 );
+  for(ii=0; ii<pTabList->nSrc; ii++){
+    createMask(pMaskSet, pTabList->a[ii].iCursor);
 #ifndef SQLITE_OMIT_VIRTUALTABLE
-    if( ALWAYS(pTabList->a[i].pTab) && IsVirtual(pTabList->a[i].pTab) ){
-      pWC->vmask |= ((Bitmask)1 << i);
+    if( ALWAYS(pTabList->a[ii].pTab) && IsVirtual(pTabList->a[ii].pTab) ){
+      sWBI.pWC->vmask |= ((Bitmask)1 << ii);
     }
 #endif
   }
 #ifndef NDEBUG
   {
     Bitmask toTheLeft = 0;
-    for(i=0; i<pTabList->nSrc; i++){
-      Bitmask m = getMask(pMaskSet, pTabList->a[i].iCursor);
+    for(ii=0; ii<pTabList->nSrc; ii++){
+      Bitmask m = getMask(pMaskSet, pTabList->a[ii].iCursor);
       assert( (m-1)==toTheLeft );
       toTheLeft |= m;
     }
@@ -108422,7 +107445,7 @@ 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, pWC);
+  exprAnalyzeAll(pTabList, sWBI.pWC);
   if( db->mallocFailed ){
     goto whereBeginError;
   }
@@ -108431,7 +107454,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
   ** If it is, then set pDistinct to NULL and WhereInfo.eDistinct to
   ** WHERE_DISTINCT_UNIQUE to tell the caller to ignore the DISTINCT.
   */
-  if( pDistinct && isDistinctRedundant(pParse, pTabList, pWC, pDistinct) ){
+  if( pDistinct && isDistinctRedundant(pParse, pTabList, sWBI.pWC, pDistinct) ){
     pDistinct = 0;
     pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
   }
@@ -108451,10 +107474,13 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
   ** This loop also figures out the nesting order of tables in the FROM
   ** clause.
   */
-  notReady = ~(Bitmask)0;
+  sWBI.notValid = ~(Bitmask)0;
+  sWBI.pOrderBy = pOrderBy;
+  sWBI.n = nTabList;
+  sWBI.pDistinct = pDistinct;
   andFlags = ~0;
   WHERETRACE(("*** Optimizer Start ***\n"));
-  for(i=iFrom=0, pLevel=pWInfo->a; i<nTabList; i++, pLevel++){
+  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 */
@@ -108466,7 +107492,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
 
     memset(&bestPlan, 0, sizeof(bestPlan));
     bestPlan.rCost = SQLITE_BIG_DBL;
-    WHERETRACE(("*** Begin search for loop %d ***\n", i));
+    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
@@ -108482,8 +107508,8 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
     ** 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 notReady.  If no notReady terms are
-    ** used then the "optimal" query plan works.
+    ** 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
@@ -108514,58 +107540,64 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
     nUnconstrained = 0;
     notIndexed = 0;
     for(isOptimal=(iFrom<nTabList-1); isOptimal>=0 && bestJ<0; isOptimal--){
-      Bitmask mask;             /* Mask of tables not yet ready */
-      for(j=iFrom, pTabItem=&pTabList->a[j]; j<nTabList; j++, pTabItem++){
+      for(j=iFrom, sWBI.pSrc=&pTabList->a[j]; j<nTabList; j++, sWBI.pSrc++){
         int doNotReorder;    /* True if this table should not be reordered */
-        WhereCost sCost;     /* Cost information from best[Virtual]Index() */
-        ExprList *pOrderBy;  /* ORDER BY clause for index to optimize */
-        ExprList *pDist;     /* DISTINCT clause for index to optimize */
   
-        doNotReorder =  (pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0;
+        doNotReorder =  (sWBI.pSrc->jointype & (JT_LEFT|JT_CROSS))!=0;
         if( j!=iFrom && doNotReorder ) break;
-        m = getMask(pMaskSet, pTabItem->iCursor);
-        if( (m & notReady)==0 ){
+        m = getMask(pMaskSet, sWBI.pSrc->iCursor);
+        if( (m & sWBI.notValid)==0 ){
           if( j==iFrom ) iFrom++;
           continue;
         }
-        mask = (isOptimal ? m : notReady);
-        pOrderBy = ((i==0 && ppOrderBy )?*ppOrderBy:0);
-        pDist = (i==0 ? pDistinct : 0);
-        if( pTabItem->pIndex==0 ) nUnconstrained++;
+        sWBI.notReady = (isOptimal ? m : sWBI.notValid);
+        if( sWBI.pSrc->pIndex==0 ) nUnconstrained++;
   
-        WHERETRACE(("=== trying table %d with isOptimal=%d ===\n",
-                    j, isOptimal));
-        assert( pTabItem->pTab );
+        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(pTabItem->pTab) ){
-          sqlite3_index_info **pp = &pWInfo->a[j].pIdxInfo;
-          bestVirtualIndex(pParse, pWC, pTabItem, mask, notReady, pOrderBy,
-                           &sCost, pp);
+        if( IsVirtual(sWBI.pSrc->pTab) ){
+          sWBI.ppIdxInfo = &pWInfo->a[j].pIdxInfo;
+          bestVirtualIndex(&sWBI);
         }else 
 #endif
         {
-          bestBtreeIndex(pParse, pWC, pTabItem, mask, notReady, pOrderBy,
-              pDist, &sCost);
+          bestBtreeIndex(&sWBI);
         }
-        assert( isOptimal || (sCost.used&notReady)==0 );
+        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( pTabItem->pIndex==0 
-                  || (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0
-                  || sCost.plan.u.pIdx==pTabItem->pIndex );
+        assert( sWBI.pSrc->pIndex==0 
+                  || (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0
+                  || sWBI.cost.plan.u.pIdx==sWBI.pSrc->pIndex );
 
-        if( isOptimal && (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){
+        if( isOptimal && (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){
           notIndexed |= m;
         }
+        if( isOptimal ){
+          pWInfo->a[j].rOptCost = sWBI.cost.rCost;
+        }else if( iFrom<nTabList-1 ){
+          /* If two or more tables have nearly the same outer loop cost,
+          ** 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.
+        **       yet run.  (In other words, it must not depend on tables
+        **       in inner loops.)
         **
-        **   (2) A full-table-scan plan cannot supercede indexed plan unless
-        **       the full-table-scan is an "optimal" plan as defined above.
+        **   (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
@@ -108576,51 +107608,53 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
         **       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 or else the
-        **       cost must be the same and the number of rows must be lower.
+        **   (4) The plan cost must be lower than prior plans, where "cost"
+        **       is defined by the compareCost() function above. 
         */
-        if( (sCost.used&notReady)==0                       /* (1) */
-            && (bestJ<0 || (notIndexed&m)!=0               /* (2) */
-                || (bestPlan.plan.wsFlags & WHERE_NOT_FULLSCAN)==0
-                || (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0)
-            && (nUnconstrained==0 || pTabItem->pIndex==0   /* (3) */
-                || NEVER((sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0))
-            && (bestJ<0 || sCost.rCost<bestPlan.rCost      /* (4) */
-                || (sCost.rCost<=bestPlan.rCost 
-                 && sCost.plan.nRow<bestPlan.plan.nRow))
+        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 is best so far"
-                      " with cost=%g and nRow=%g\n",
-                      j, sCost.rCost, sCost.plan.nRow));
-          bestPlan = sCost;
+          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;
         }
         if( doNotReorder ) break;
       }
     }
     assert( bestJ>=0 );
-    assert( notReady & getMask(pMaskSet, pTabList->a[bestJ].iCursor) );
-    WHERETRACE(("*** Optimizer selects table %d for loop %d"
-                " with cost=%g and nRow=%g\n",
-                bestJ, pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow));
-    /* The ALWAYS() that follows was added to hush up clang scan-build */
-    if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 && ALWAYS(ppOrderBy) ){
-      *ppOrderBy = 0;
-    }
+    assert( sWBI.notValid & getMask(pMaskSet, pTabList->a[bestJ].iCursor) );
+    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) ){
-      pLevel->iIdxCur = pParse->nTab++;
+      if( (wctrlFlags & WHERE_ONETABLE_ONLY) 
+       && (bestPlan.plan.wsFlags & WHERE_TEMP_INDEX)==0 
+      ){
+        pLevel->iIdxCur = iIdxCur;
+      }else{
+        pLevel->iIdxCur = pParse->nTab++;
+      }
     }else{
       pLevel->iIdxCur = -1;
     }
-    notReady &= ~getMask(pMaskSet, pTabList->a[bestJ].iCursor);
+    sWBI.notValid &= ~getMask(pMaskSet, pTabList->a[bestJ].iCursor);
     pLevel->iFrom = (u8)bestJ;
     if( bestPlan.plan.nRow>=(double)1 ){
       pParse->nQueryLoop *= bestPlan.plan.nRow;
@@ -108648,12 +107682,19 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
   if( pParse->nErr || db->mallocFailed ){
     goto whereBeginError;
   }
+  if( nTabList ){
+    pLevel--;
+    pWInfo->nOBSat = pLevel->plan.nOBSat;
+  }else{
+    pWInfo->nOBSat = 0;
+  }
 
   /* If the total query only selects a single row, then the ORDER BY
   ** clause is irrelevant.
   */
-  if( (andFlags & WHERE_UNIQUE)!=0 && ppOrderBy ){
-    *ppOrderBy = 0;
+  if( (andFlags & WHERE_UNIQUE)!=0 && pOrderBy ){
+    assert( nTabList==0 || (pLevel->plan.wsFlags & WHERE_ALL_UNIQUE)!=0 );
+    pWInfo->nOBSat = pOrderBy->nExpr;
   }
 
   /* If the caller is an UPDATE or DELETE statement that is requesting
@@ -108673,13 +107714,13 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
   sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
   notReady = ~(Bitmask)0;
   pWInfo->nRowOut = (double)1;
-  for(i=0, pLevel=pWInfo->a; i<nTabList; i++, pLevel++){
+  for(ii=0, pLevel=pWInfo->a; ii<nTabList; ii++, pLevel++){
     Table *pTab;     /* Table to open */
     int iDb;         /* Index of database containing table/index */
+    struct SrcList_item *pTabItem;
 
     pTabItem = &pTabList->a[pLevel->iFrom];
     pTab = pTabItem->pTab;
-    pLevel->iTabCur = pTabItem->iCursor;
     pWInfo->nRowOut *= pLevel->plan.nRow;
     iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
     if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){
@@ -108690,6 +107731,8 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
       const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
       int iCur = pTabItem->iCursor;
       sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB);
+    }else if( IsVirtual(pTab) ){
+      /* noop */
     }else
 #endif
     if( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0
@@ -108711,21 +107754,21 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
     }
 #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
     if( (pLevel->plan.wsFlags & WHERE_TEMP_INDEX)!=0 ){
-      constructAutomaticIndex(pParse, pWC, pTabItem, notReady, pLevel);
+      constructAutomaticIndex(pParse, sWBI.pWC, pTabItem, notReady, pLevel);
     }else
 #endif
     if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){
       Index *pIx = pLevel->plan.u.pIdx;
       KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx);
-      int iIdxCur = pLevel->iIdxCur;
+      int iIndexCur = pLevel->iIdxCur;
       assert( pIx->pSchema==pTab->pSchema );
-      assert( iIdxCur>=0 );
-      sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIx->tnum, iDb,
+      assert( iIndexCur>=0 );
+      sqlite3VdbeAddOp4(v, OP_OpenRead, iIndexCur, pIx->tnum, iDb,
                         (char*)pKey, P4_KEYINFO_HANDOFF);
       VdbeComment((v, "%s", pIx->zName));
     }
     sqlite3CodeVerifySchema(pParse, iDb);
-    notReady &= ~getMask(pWC->pMaskSet, pTabItem->iCursor);
+    notReady &= ~getMask(sWBI.pWC->pMaskSet, pTabItem->iCursor);
   }
   pWInfo->iTop = sqlite3VdbeCurrentAddr(v);
   if( db->mallocFailed ) goto whereBeginError;
@@ -108735,10 +107778,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
   ** program.
   */
   notReady = ~(Bitmask)0;
-  for(i=0; i<nTabList; i++){
-    pLevel = &pWInfo->a[i];
-    explainOneScan(pParse, pTabList, pLevel, i, pLevel->iFrom, wctrlFlags);
-    notReady = codeOneLoopStart(pWInfo, i, wctrlFlags, notReady);
+  for(ii=0; ii<nTabList; ii++){
+    pLevel = &pWInfo->a[ii];
+    explainOneScan(pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags);
+    notReady = codeOneLoopStart(pWInfo, ii, wctrlFlags, notReady);
     pWInfo->iContinue = pLevel->addrCont;
   }
 
@@ -108749,16 +107792,20 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
   ** the index is listed as "{}".  If the primary key is used the
   ** index name is '*'.
   */
-  for(i=0; i<nTabList; i++){
+  for(ii=0; ii<nTabList; ii++){
     char *z;
     int n;
-    pLevel = &pWInfo->a[i];
+    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( pLevel->plan.wsFlags & WHERE_IDX_ONLY ){
+      if( (w & WHERE_IDX_ONLY)!=0 && (w & WHERE_COVER_SCAN)==0 ){
         memcpy(&sqlite3_query_plan[nQPlan], "{}", 2);
         nQPlan += 2;
       }else{
@@ -108767,12 +107814,12 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
       }
       sqlite3_query_plan[nQPlan++] = ' ';
     }
-    testcase( pLevel->plan.wsFlags & WHERE_ROWID_EQ );
-    testcase( pLevel->plan.wsFlags & WHERE_ROWID_RANGE );
-    if( pLevel->plan.wsFlags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
+    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( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){
+    }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);
@@ -108868,6 +107915,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
   */
   assert( pWInfo->nLevel==1 || 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 );
@@ -108897,12 +107945,15 @@ 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)!=0 && !db->mallocFailed){
+    if( pLevel->plan.wsFlags & WHERE_INDEXED ){
+      pIdx = pLevel->plan.u.pIdx;
+    }else if( pLevel->plan.wsFlags & WHERE_MULTI_OR ){
+      pIdx = pLevel->u.pCovidx;
+    }
+    if( pIdx && !db->mallocFailed){
       int k, j, last;
       VdbeOp *pOp;
-      Index *pIdx = pLevel->plan.u.pIdx;
 
-      assert( pIdx!=0 );
       pOp = sqlite3VdbeGetOp(v, pWInfo->iTop);
       last = sqlite3VdbeCurrentAddr(v);
       for(k=pWInfo->iTop; k<last; k++, pOp++){
@@ -111627,7 +110678,7 @@ static void yy_reduce(
         break;
       case 194: /* expr ::= expr COLLATE ids */
 {
-  yygotominor.yy342.pExpr = sqlite3ExprSetCollByToken(pParse, yymsp[-2].minor.yy342.pExpr, &yymsp[0].minor.yy0);
+  yygotominor.yy342.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy342.pExpr, &yymsp[0].minor.yy0);
   yygotominor.yy342.zStart = yymsp[-2].minor.yy342.zStart;
   yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
 }
@@ -111886,11 +110937,7 @@ static void yy_reduce(
         break;
       case 247: /* idxlist ::= idxlist COMMA nm collate sortorder */
 {
-  Expr *p = 0;
-  if( yymsp[-1].minor.yy0.n>0 ){
-    p = sqlite3Expr(pParse->db, TK_COLUMN, 0);
-    sqlite3ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0);
-  }
+  Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
   yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, p);
   sqlite3ExprListSetName(pParse,yygotominor.yy442,&yymsp[-2].minor.yy0,1);
   sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
@@ -111899,11 +110946,7 @@ static void yy_reduce(
         break;
       case 248: /* idxlist ::= nm collate sortorder */
 {
-  Expr *p = 0;
-  if( yymsp[-1].minor.yy0.n>0 ){
-    p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
-    sqlite3ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0);
-  }
+  Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
   yygotominor.yy442 = sqlite3ExprListAppend(pParse,0, p);
   sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1);
   sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
@@ -112152,6 +111195,7 @@ static void yy_reduce(
       /* (326) anylist ::= anylist ANY */ yytestcase(yyruleno==326);
         break;
   };
+  assert( yyruleno>=0 && yyruleno<sizeof(yyRuleInfo)/sizeof(yyRuleInfo[0]) );
   yygoto = yyRuleInfo[yyruleno].lhs;
   yysize = yyRuleInfo[yyruleno].nrhs;
   yypParser->yyidx -= yysize;
@@ -113717,6 +112761,13 @@ SQLITE_API int sqlite3_initialize(void){
   */
   if( sqlite3GlobalConfig.isInit ) return SQLITE_OK;
 
+#ifdef SQLITE_ENABLE_SQLLOG
+  {
+    extern void sqlite3_init_sqllog(void);
+    sqlite3_init_sqllog();
+  }
+#endif
+
   /* Make sure the mutex subsystem is initialized.  If unable to 
   ** initialize the mutex subsystem, return early with the error.
   ** If the system is so sick that we are unable to allocate a mutex,
@@ -114060,6 +113111,20 @@ SQLITE_API int sqlite3_config(int op, ...){
       break;
     }
 
+    case SQLITE_CONFIG_COVERING_INDEX_SCAN: {
+      sqlite3GlobalConfig.bUseCis = va_arg(ap, int);
+      break;
+    }
+
+#ifdef SQLITE_ENABLE_SQLLOG
+    case SQLITE_CONFIG_SQLLOG: {
+      typedef void(*SQLLOGFUNC_t)(void*, sqlite3*, const char*, int);
+      sqlite3GlobalConfig.xSqllog = va_arg(ap, SQLLOGFUNC_t);
+      sqlite3GlobalConfig.pSqllogArg = va_arg(ap, void *);
+      break;
+    }
+#endif
+
     default: {
       rc = SQLITE_ERROR;
       break;
@@ -114351,12 +113416,24 @@ static void disconnectAllVtab(sqlite3 *db){
 }
 
 /*
-** Close an existing SQLite database
+** Return TRUE if database connection db has unfinalized prepared
+** statements or unfinished sqlite3_backup objects.  
 */
-SQLITE_API int sqlite3_close(sqlite3 *db){
-  HashElem *i;                    /* Hash table iterator */
+static int connectionIsBusy(sqlite3 *db){
   int j;
+  assert( sqlite3_mutex_held(db->mutex) );
+  if( db->pVdbe ) return 1;
+  for(j=0; j<db->nDb; j++){
+    Btree *pBt = db->aDb[j].pBt;
+    if( pBt && sqlite3BtreeIsInBackup(pBt) ) return 1;
+  }
+  return 0;
+}
 
+/*
+** Close an existing SQLite database
+*/
+static int sqlite3Close(sqlite3 *db, int forceZombie){
   if( !db ){
     return SQLITE_OK;
   }
@@ -114377,25 +113454,70 @@ SQLITE_API int sqlite3_close(sqlite3 *db){
   */
   sqlite3VtabRollback(db);
 
-  /* If there are any outstanding VMs, return SQLITE_BUSY. */
-  if( db->pVdbe ){
-    sqlite3Error(db, SQLITE_BUSY, 
-        "unable to close due to unfinalised statements");
+  /* Legacy behavior (sqlite3_close() behavior) is to return
+  ** SQLITE_BUSY if the connection can not be closed immediately.
+  */
+  if( !forceZombie && connectionIsBusy(db) ){
+    sqlite3Error(db, SQLITE_BUSY, "unable to close due to unfinalized "
+       "statements or unfinished backups");
     sqlite3_mutex_leave(db->mutex);
     return SQLITE_BUSY;
   }
-  assert( sqlite3SafetyCheckSickOrOk(db) );
 
-  for(j=0; j<db->nDb; j++){
-    Btree *pBt = db->aDb[j].pBt;
-    if( pBt && sqlite3BtreeIsInBackup(pBt) ){
-      sqlite3Error(db, SQLITE_BUSY, 
-          "unable to close due to unfinished backup operation");
-      sqlite3_mutex_leave(db->mutex);
-      return SQLITE_BUSY;
-    }
+#ifdef SQLITE_ENABLE_SQLLOG
+  if( sqlite3GlobalConfig.xSqllog ){
+    /* Closing the handle. Fourth parameter is passed the value 2. */
+    sqlite3GlobalConfig.xSqllog(sqlite3GlobalConfig.pSqllogArg, db, 0, 2);
+  }
+#endif
+
+  /* Convert the connection into a zombie and then close it.
+  */
+  db->magic = SQLITE_MAGIC_ZOMBIE;
+  sqlite3LeaveMutexAndCloseZombie(db);
+  return SQLITE_OK;
+}
+
+/*
+** Two variations on the public interface for closing a database
+** connection. The sqlite3_close() version returns SQLITE_BUSY and
+** leaves the connection option if there are unfinalized prepared
+** statements or unfinished sqlite3_backups.  The sqlite3_close_v2()
+** version forces the connection to become a zombie if there are
+** unclosed resources, and arranges for deallocation when the last
+** prepare statement or sqlite3_backup closes.
+*/
+SQLITE_API int sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); }
+SQLITE_API int sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); }
+
+
+/*
+** Close the mutex on database connection db.
+**
+** Furthermore, if database connection db is a zombie (meaning that there
+** has been a prior call to sqlite3_close(db) or sqlite3_close_v2(db)) and
+** every sqlite3_stmt has now been finalized and every sqlite3_backup has
+** finished, then free all resources.
+*/
+SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
+  HashElem *i;                    /* Hash table iterator */
+  int j;
+
+  /* If there are outstanding sqlite3_stmt or sqlite3_backup objects
+  ** or if the connection has not yet been closed by sqlite3_close_v2(),
+  ** then just leave the mutex and return.
+  */
+  if( db->magic!=SQLITE_MAGIC_ZOMBIE || connectionIsBusy(db) ){
+    sqlite3_mutex_leave(db->mutex);
+    return;
   }
 
+  /* If we reach this point, it means that the database connection has
+  ** closed all sqlite3_stmt and sqlite3_backup objects and has been
+  ** pased to sqlite3_close (meaning that it is a zombie).  Therefore,
+  ** go ahead and free all resources.
+  */
+
   /* Free any outstanding Savepoint structures. */
   sqlite3CloseSavepoints(db);
 
@@ -114483,7 +113605,6 @@ SQLITE_API int sqlite3_close(sqlite3 *db){
     sqlite3_free(db->lookaside.pStart);
   }
   sqlite3_free(db);
-  return SQLITE_OK;
 }
 
 /*
@@ -114652,6 +113773,7 @@ SQLITE_API int sqlite3_busy_handler(
   db->busyHandler.xFunc = xBusy;
   db->busyHandler.pArg = pArg;
   db->busyHandler.nBusy = 0;
+  db->busyTimeout = 0;
   sqlite3_mutex_leave(db->mutex);
   return SQLITE_OK;
 }
@@ -114689,8 +113811,8 @@ SQLITE_API void sqlite3_progress_handler(
 */
 SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){
   if( ms>0 ){
-    db->busyTimeout = ms;
     sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db);
+    db->busyTimeout = ms;
   }else{
     sqlite3_busy_handler(db, 0, 0);
   }
@@ -115303,6 +114425,15 @@ SQLITE_API int sqlite3_extended_errcode(sqlite3 *db){
   return db->errCode;
 }
 
+/*
+** Return a string that describes the kind of error specified in the
+** argument.  For now, this simply calls the internal sqlite3ErrStr()
+** function.
+*/
+SQLITE_API const char *sqlite3_errstr(int rc){
+  return sqlite3ErrStr(rc);
+}
+
 /*
 ** Create a new collating function for database "db".  The name is zName
 ** and the encoding is enc.
@@ -115972,6 +115103,13 @@ opendb_out:
     db->magic = SQLITE_MAGIC_SICK;
   }
   *ppDb = db;
+#ifdef SQLITE_ENABLE_SQLLOG
+  if( sqlite3GlobalConfig.xSqllog ){
+    /* Opening a db handle. Fourth parameter is passed 0. */
+    void *pArg = sqlite3GlobalConfig.pSqllogArg;
+    sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0);
+  }
+#endif
   return sqlite3ApiExit(0, rc);
 }
 
@@ -116277,7 +115415,7 @@ SQLITE_API int sqlite3_table_column_metadata(
     zDataType = pCol->zType;
     zCollSeq = pCol->zColl;
     notnull = pCol->notNull!=0;
-    primarykey  = pCol->isPrimKey!=0;
+    primarykey  = (pCol->colFlags & COLFLAG_PRIMKEY)!=0;
     autoinc = pTab->iPKey==iCol && (pTab->tabFlags & TF_Autoincrement)!=0;
   }else{
     zDataType = "INTEGER";
@@ -116540,8 +115678,7 @@ SQLITE_API int sqlite3_test_control(int op, ...){
     */
     case SQLITE_TESTCTRL_OPTIMIZATIONS: {
       sqlite3 *db = va_arg(ap, sqlite3*);
-      int x = va_arg(ap,int);
-      db->flags = (x & SQLITE_OptMask) | (db->flags & ~SQLITE_OptMask);
+      db->dbOptFlags = (u16)(va_arg(ap, int) & 0xffff);
       break;
     }
 
@@ -118027,10 +117164,20 @@ SQLITE_PRIVATE int sqlite3Fts3ReadBlock(Fts3Table*, sqlite3_int64, char **, int*
 SQLITE_PRIVATE int sqlite3Fts3SelectDoctotal(Fts3Table *, sqlite3_stmt **);
 SQLITE_PRIVATE int sqlite3Fts3SelectDocsize(Fts3Table *, sqlite3_int64, sqlite3_stmt **);
 
+#ifndef SQLITE_DISABLE_FTS4_DEFERRED
 SQLITE_PRIVATE void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *);
 SQLITE_PRIVATE int sqlite3Fts3DeferToken(Fts3Cursor *, Fts3PhraseToken *, int);
 SQLITE_PRIVATE int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *);
 SQLITE_PRIVATE void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *);
+SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *);
+#else
+# define sqlite3Fts3FreeDeferredTokens(x)
+# define sqlite3Fts3DeferToken(x,y,z) SQLITE_OK
+# define sqlite3Fts3CacheDeferredDoclists(x) SQLITE_OK
+# define sqlite3Fts3FreeDeferredDoclists(x)
+# define sqlite3Fts3DeferredTokenList(x,y,z) SQLITE_OK
+#endif
+
 SQLITE_PRIVATE void sqlite3Fts3SegmentsClose(Fts3Table *);
 SQLITE_PRIVATE int sqlite3Fts3MaxLevel(Fts3Table *, int *);
 
@@ -118139,8 +117286,6 @@ SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iC
 SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *);
 SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr);
 
-SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *);
-
 /* fts3_unicode2.c (functions generated by parsing unicode text files) */
 #ifdef SQLITE_ENABLE_FTS4_UNICODE61
 SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int, int);
@@ -122298,6 +121443,7 @@ static int fts3EvalStart(Fts3Cursor *pCsr){
   fts3EvalAllocateReaders(pCsr, pCsr->pExpr, &nToken, &nOr, &rc);
 
   /* Determine which, if any, tokens in the expression should be deferred. */
+#ifndef SQLITE_DISABLE_FTS4_DEFERRED
   if( rc==SQLITE_OK && nToken>1 && pTab->bFts4 ){
     Fts3TokenAndCost *aTC;
     Fts3Expr **apOr;
@@ -122328,6 +121474,7 @@ static int fts3EvalStart(Fts3Cursor *pCsr){
       sqlite3_free(aTC);
     }
   }
+#endif
 
   fts3EvalStartReaders(pCsr, pCsr->pExpr, 1, &rc);
   return rc;
@@ -122603,35 +121750,39 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){
       nTmp += p->pRight->pPhrase->doclist.nList;
     }
     nTmp += p->pPhrase->doclist.nList;
-    aTmp = sqlite3_malloc(nTmp*2);
-    if( !aTmp ){
-      *pRc = SQLITE_NOMEM;
+    if( nTmp==0 ){
       res = 0;
     }else{
-      char *aPoslist = p->pPhrase->doclist.pList;
-      int nToken = p->pPhrase->nToken;
+      aTmp = sqlite3_malloc(nTmp*2);
+      if( !aTmp ){
+        *pRc = SQLITE_NOMEM;
+        res = 0;
+      }else{
+        char *aPoslist = p->pPhrase->doclist.pList;
+        int nToken = p->pPhrase->nToken;
 
-      for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){
-        Fts3Phrase *pPhrase = p->pRight->pPhrase;
-        int nNear = p->nNear;
-        res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
-      }
-  
-      aPoslist = pExpr->pRight->pPhrase->doclist.pList;
-      nToken = pExpr->pRight->pPhrase->nToken;
-      for(p=pExpr->pLeft; p && res; p=p->pLeft){
-        int nNear;
-        Fts3Phrase *pPhrase;
-        assert( p->pParent && p->pParent->pLeft==p );
-        nNear = p->pParent->nNear;
-        pPhrase = (
-            p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase
-        );
-        res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
+        for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){
+          Fts3Phrase *pPhrase = p->pRight->pPhrase;
+          int nNear = p->nNear;
+          res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
+        }
+
+        aPoslist = pExpr->pRight->pPhrase->doclist.pList;
+        nToken = pExpr->pRight->pPhrase->nToken;
+        for(p=pExpr->pLeft; p && res; p=p->pLeft){
+          int nNear;
+          Fts3Phrase *pPhrase;
+          assert( p->pParent && p->pParent->pLeft==p );
+          nNear = p->pParent->nNear;
+          pPhrase = (
+              p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase
+              );
+          res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
+        }
       }
-    }
 
-    sqlite3_free(aTmp);
+      sqlite3_free(aTmp);
+    }
   }
 
   return res;
@@ -122711,6 +121862,7 @@ static int fts3EvalTestExpr(
         break;
 
       default: {
+#ifndef SQLITE_DISABLE_FTS4_DEFERRED
         if( pCsr->pDeferred 
          && (pExpr->iDocid==pCsr->iPrevId || pExpr->bDeferred)
         ){
@@ -122722,7 +121874,9 @@ static int fts3EvalTestExpr(
           *pRc = fts3EvalDeferredPhrase(pCsr, pPhrase);
           bHit = (pPhrase->doclist.pList!=0);
           pExpr->iDocid = pCsr->iPrevId;
-        }else{
+        }else
+#endif
+        {
           bHit = (pExpr->bEof==0 && pExpr->iDocid==pCsr->iPrevId);
         }
         break;
@@ -123866,7 +123020,7 @@ static int getNextToken(
   rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, n, &pCursor);
   if( rc==SQLITE_OK ){
     const char *zToken;
-    int nToken, iStart, iEnd, iPosition;
+    int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0;
     int nByte;                               /* total space to allocate */
 
     rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition);
@@ -123981,7 +123135,7 @@ static int getNextString(
     int ii;
     for(ii=0; rc==SQLITE_OK; ii++){
       const char *zByte;
-      int nByte, iBegin, iEnd, iPos;
+      int nByte = 0, iBegin = 0, iEnd = 0, iPos = 0;
       rc = pModule->xNext(pCursor, &zByte, &nByte, &iBegin, &iEnd, &iPos);
       if( rc==SQLITE_OK ){
         Fts3PhraseToken *pToken;
@@ -125978,10 +125132,10 @@ static void testFunc(
   const char *azArg[64];
 
   const char *zToken;
-  int nToken;
-  int iStart;
-  int iEnd;
-  int iPos;
+  int nToken = 0;
+  int iStart = 0;
+  int iEnd = 0;
+  int iPos = 0;
   int i;
 
   Tcl_Obj *pRet;
@@ -127228,16 +126382,16 @@ static int fts3PendingTermsAdd(
   int iLangid,                    /* Language id to use */
   const char *zText,              /* Text of document to be inserted */
   int iCol,                       /* Column into which text is being inserted */
-  u32 *pnWord                     /* OUT: Number of tokens inserted */
+  u32 *pnWord                     /* IN/OUT: Incr. by number tokens inserted */
 ){
   int rc;
-  int iStart;
-  int iEnd;
-  int iPos;
+  int iStart = 0;
+  int iEnd = 0;
+  int iPos = 0;
   int nWord = 0;
 
   char const *zToken;
-  int nToken;
+  int nToken = 0;
 
   sqlite3_tokenizer *pTokenizer = p->pTokenizer;
   sqlite3_tokenizer_module const *pModule = pTokenizer->pModule;
@@ -127292,7 +126446,7 @@ static int fts3PendingTermsAdd(
   }
 
   pModule->xClose(pCsr);
-  *pnWord = nWord;
+  *pnWord += nWord;
   return (rc==SQLITE_DONE ? SQLITE_OK : rc);
 }
 
@@ -127496,11 +126650,13 @@ static void fts3DeleteTerms(
   int *pRC,               /* Result code */
   Fts3Table *p,           /* The FTS table to delete from */
   sqlite3_value *pRowid,  /* The docid to be deleted */
-  u32 *aSz                /* Sizes of deleted document written here */
+  u32 *aSz,               /* Sizes of deleted document written here */
+  int *pbFound            /* OUT: Set to true if row really does exist */
 ){
   int rc;
   sqlite3_stmt *pSelect;
 
+  assert( *pbFound==0 );
   if( *pRC ) return;
   rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pSelect, &pRowid);
   if( rc==SQLITE_OK ){
@@ -127518,6 +126674,7 @@ static void fts3DeleteTerms(
         *pRC = rc;
         return;
       }
+      *pbFound = 1;
     }
     rc = sqlite3_reset(pSelect);
   }else{
@@ -129421,7 +128578,7 @@ static int fts3SegmentMerge(
 
   if( iLevel==FTS3_SEGCURSOR_ALL ){
     /* This call is to merge all segments in the database to a single
-    ** segment. The level of the new segment is equal to the the numerically 
+    ** segment. The level of the new segment is equal to the numerically
     ** greatest segment level currently present in the database for this
     ** index. The idx of the new segment is always 0.  */
     if( csr.nSegment==1 ){
@@ -129742,7 +128899,7 @@ static int fts3DoRebuild(Fts3Table *p){
       int iCol;
       int iLangid = langidFromSelect(p, pStmt);
       rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pStmt, 0));
-      aSz[p->nColumn] = 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]);
@@ -130051,7 +129208,7 @@ static int fts3IncrmergePush(
         pNode->key.n = nTerm;
       }
     }else{
-      /* Otherwise, flush the the current node of layer iLayer to disk.
+      /* Otherwise, flush the current node of layer iLayer to disk.
       ** Then allocate a new, empty sibling node. The key will be written
       ** into the parent of this node. */
       rc = fts3WriteSegment(p, pNode->iBlock, pNode->block.a, pNode->block.n);
@@ -131386,9 +130543,9 @@ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){
         rc = sqlite3Fts3OpenTokenizer(p->pTokenizer, iLang, zText, nText, &pT);
         while( rc==SQLITE_OK ){
           char const *zToken;       /* Buffer containing token */
-          int nToken;               /* Number of bytes in token */
-          int iDum1, iDum2;         /* Dummy variables */
-          int iPos;                 /* Position of token in zText */
+          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(pT, &zToken, &nToken, &iDum1, &iDum2, &iPos);
           if( rc==SQLITE_OK ){
@@ -131498,6 +130655,7 @@ static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){
   return rc;
 }
 
+#ifndef SQLITE_DISABLE_FTS4_DEFERRED
 /*
 ** Delete all cached deferred doclists. Deferred doclists are cached
 ** (allocated) by the sqlite3Fts3CacheDeferredDoclists() function.
@@ -131554,9 +130712,9 @@ SQLITE_PRIVATE int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *pCsr){
       rc = sqlite3Fts3OpenTokenizer(pT, pCsr->iLangid, zText, -1, &pTC);
       while( rc==SQLITE_OK ){
         char const *zToken;       /* Buffer containing token */
-        int nToken;               /* Number of bytes in token */
-        int iDum1, iDum2;         /* Dummy variables */
-        int iPos;                 /* Position of token in zText */
+        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){
@@ -131635,6 +130793,7 @@ SQLITE_PRIVATE int sqlite3Fts3DeferToken(
 
   return SQLITE_OK;
 }
+#endif
 
 /*
 ** SQLite value pRowid contains the rowid of a row that may or may not be
@@ -131644,28 +130803,32 @@ SQLITE_PRIVATE int sqlite3Fts3DeferToken(
 static int fts3DeleteByRowid(
   Fts3Table *p, 
   sqlite3_value *pRowid, 
-  int *pnDoc,
+  int *pnChng,                    /* IN/OUT: Decrement if row is deleted */
   u32 *aSzDel
 ){
-  int isEmpty = 0;
-  int rc = fts3IsEmpty(p, pRowid, &isEmpty);
-  if( rc==SQLITE_OK ){
-    if( isEmpty ){
-      /* Deleting this row means the whole table is empty. In this case
-      ** delete the contents of all three tables and throw away any
-      ** data in the pendingTerms hash table.  */
-      rc = fts3DeleteAll(p, 1);
-      *pnDoc = *pnDoc - 1;
-    }else{
-      fts3DeleteTerms(&rc, p, pRowid, aSzDel);
-      if( p->zContentTbl==0 ){
-        fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, &pRowid);
-        if( sqlite3_changes(p->db) ) *pnDoc = *pnDoc - 1;
+  int rc = SQLITE_OK;             /* Return code */
+  int bFound = 0;                 /* True if *pRowid really is in the table */
+
+  fts3DeleteTerms(&rc, p, pRowid, aSzDel, &bFound);
+  if( bFound && rc==SQLITE_OK ){
+    int isEmpty = 0;              /* Deleting *pRowid leaves the table empty */
+    rc = fts3IsEmpty(p, pRowid, &isEmpty);
+    if( rc==SQLITE_OK ){
+      if( isEmpty ){
+        /* Deleting this row means the whole table is empty. In this case
+        ** delete the contents of all three tables and throw away any
+        ** data in the pendingTerms hash table.  */
+        rc = fts3DeleteAll(p, 1);
+        *pnChng = 0;
+        memset(aSzDel, 0, sizeof(u32) * (p->nColumn+1) * 2);
       }else{
-        *pnDoc = *pnDoc - 1;
-      }
-      if( p->bHasDocsize ){
-        fts3SqlExec(&rc, p, SQL_DELETE_DOCSIZE, &pRowid);
+        *pnChng = *pnChng - 1;
+        if( p->zContentTbl==0 ){
+          fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, &pRowid);
+        }
+        if( p->bHasDocsize ){
+          fts3SqlExec(&rc, p, SQL_DELETE_DOCSIZE, &pRowid);
+        }
       }
     }
   }
@@ -131696,7 +130859,7 @@ SQLITE_PRIVATE int sqlite3Fts3UpdateMethod(
   int rc = SQLITE_OK;             /* Return Code */
   int isRemove = 0;               /* True for an UPDATE or DELETE */
   u32 *aSzIns = 0;                /* Sizes of inserted documents */
-  u32 *aSzDel;                    /* Sizes of deleted documents */
+  u32 *aSzDel = 0;                /* Sizes of deleted documents */
   int nChng = 0;                  /* Net change in number of documents */
   int bInsertDone = 0;
 
@@ -131724,13 +130887,13 @@ SQLITE_PRIVATE int sqlite3Fts3UpdateMethod(
   }
 
   /* Allocate space to hold the change in document sizes */
-  aSzIns = sqlite3_malloc( sizeof(aSzIns[0])*(p->nColumn+1)*2 );
-  if( aSzIns==0 ){
+  aSzDel = sqlite3_malloc( sizeof(aSzDel[0])*(p->nColumn+1)*2 );
+  if( aSzDel==0 ){
     rc = SQLITE_NOMEM;
     goto update_out;
   }
-  aSzDel = &aSzIns[p->nColumn+1];
-  memset(aSzIns, 0, sizeof(aSzIns[0])*(p->nColumn+1)*2);
+  aSzIns = &aSzDel[p->nColumn+1];
+  memset(aSzDel, 0, sizeof(aSzDel[0])*(p->nColumn+1)*2);
 
   /* If this is an INSERT operation, or an UPDATE that modifies the rowid
   ** value, then this operation requires constraint handling.
@@ -131815,7 +130978,7 @@ SQLITE_PRIVATE int sqlite3Fts3UpdateMethod(
   }
 
  update_out:
-  sqlite3_free(aSzIns);
+  sqlite3_free(aSzDel);
   sqlite3Fts3SegmentsClose(p);
   return rc;
 }
@@ -132423,7 +131586,7 @@ static int fts3SnippetShift(
         return rc;
       }
       while( rc==SQLITE_OK && iCurrent<(nSnippet+nDesired) ){
-        const char *ZDUMMY; int DUMMY1, DUMMY2, DUMMY3;
+        const char *ZDUMMY; int DUMMY1 = 0, DUMMY2 = 0, DUMMY3 = 0;
         rc = pMod->xNext(pC, &ZDUMMY, &DUMMY1, &DUMMY2, &DUMMY3, &iCurrent);
       }
       pMod->xClose(pC);
@@ -132467,8 +131630,6 @@ static int fts3SnippetText(
   int iCol = pFragment->iCol+1;   /* Query column to extract text from */
   sqlite3_tokenizer_module *pMod; /* Tokenizer module methods object */
   sqlite3_tokenizer_cursor *pC;   /* Tokenizer cursor open on zDoc/nDoc */
-  const char *ZDUMMY;             /* Dummy argument used with tokenizer */
-  int DUMMY1;                     /* Dummy argument used with tokenizer */
   
   zDoc = (const char *)sqlite3_column_text(pCsr->pStmt, iCol);
   if( zDoc==0 ){
@@ -132487,10 +131648,23 @@ static int fts3SnippetText(
   }
 
   while( rc==SQLITE_OK ){
-    int iBegin;                   /* Offset in zDoc of start of token */
-    int iFin;                     /* Offset in zDoc of end of token */
-    int isHighlight;              /* True for highlighted terms */
-
+    const char *ZDUMMY;           /* Dummy argument used with tokenizer */
+    int DUMMY1 = -1;              /* Dummy argument used with tokenizer */
+    int iBegin = 0;               /* Offset in zDoc of start of token */
+    int iFin = 0;                 /* Offset in zDoc of end of token */
+    int isHighlight = 0;          /* True for highlighted terms */
+
+    /* Variable DUMMY1 is initialized to a negative value above. Elsewhere
+    ** in the FTS code the variable that the third argument to xNext points to
+    ** is initialized to zero before the first (*but not necessarily
+    ** subsequent*) call to xNext(). This is done for a particular application
+    ** that needs to know whether or not the tokenizer is being used for
+    ** snippet generation or for some other purpose.
+    **
+    ** Extreme care is required when writing code to depend on this
+    ** initialization. It is not a documented part of the tokenizer interface.
+    ** If a tokenizer is used directly by any code outside of FTS, this
+    ** convention might not be respected.  */
     rc = pMod->xNext(pC, &ZDUMMY, &DUMMY1, &iBegin, &iFin, &iCurrent);
     if( rc!=SQLITE_OK ){
       if( rc==SQLITE_DONE ){
@@ -133180,8 +132354,6 @@ SQLITE_PRIVATE void sqlite3Fts3Offsets(
 ){
   Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
   sqlite3_tokenizer_module const *pMod = pTab->pTokenizer->pModule;
-  const char *ZDUMMY;             /* Dummy argument used with xNext() */
-  int NDUMMY;                     /* Dummy argument used with xNext() */
   int rc;                         /* Return Code */
   int nToken;                     /* Number of tokens in query */
   int iCol;                       /* Column currently being processed */
@@ -133214,9 +132386,11 @@ SQLITE_PRIVATE void sqlite3Fts3Offsets(
   */
   for(iCol=0; iCol<pTab->nColumn; iCol++){
     sqlite3_tokenizer_cursor *pC; /* Tokenizer cursor */
-    int iStart;
-    int iEnd;
-    int iCurrent;
+    const char *ZDUMMY;           /* Dummy argument used with xNext() */
+    int NDUMMY = 0;               /* Dummy argument used with xNext() */
+    int iStart = 0;
+    int iEnd = 0;
+    int iCurrent = 0;
     const char *zDoc;
     int nDoc;
 
@@ -133899,7 +133073,7 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int c){
     }
     assert( aEntry[0]<key );
     assert( key>=aEntry[iRes] );
-    return (c >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF)));
+    return (((unsigned int)c) >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF)));
   }
   return 1;
 }
@@ -136780,7 +135954,7 @@ static int newRowid(Rtree *pRtree, i64 *piRowid){
 */
 static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){
   int rc;                         /* Return code */
-  RtreeNode *pLeaf;               /* Leaf node containing record iDelete */
+  RtreeNode *pLeaf = 0;           /* Leaf node containing record iDelete */
   int iCell;                      /* Index of iDelete cell in pLeaf */
   RtreeNode *pRoot;               /* Root node of rtree structure */
 
@@ -136983,7 +136157,7 @@ static int rtreeUpdate(
   */
   if( rc==SQLITE_OK && nData>1 ){
     /* Insert the new record into the r-tree */
-    RtreeNode *pLeaf;
+    RtreeNode *pLeaf = 0;
 
     /* Figure out the rowid of the new row. */
     if( bHaveRowid==0 ){
@@ -138099,7 +137273,7 @@ static int icuOpen(
   nChar = nInput+1;
   pCsr = (IcuCursor *)sqlite3_malloc(
       sizeof(IcuCursor) +                /* IcuCursor */
-      nChar * sizeof(UChar) +            /* IcuCursor.aChar[] */
+      ((nChar+3)&~3) * sizeof(UChar) +   /* IcuCursor.aChar[] */
       (nChar+1) * sizeof(int)            /* IcuCursor.aOffset[] */
   );
   if( !pCsr ){
@@ -138107,7 +137281,7 @@ static int icuOpen(
   }
   memset(pCsr, 0, sizeof(IcuCursor));
   pCsr->aChar = (UChar *)&pCsr[1];
-  pCsr->aOffset = (int *)&pCsr->aChar[nChar];
+  pCsr->aOffset = (int *)&pCsr->aChar[(nChar+3)&~3];
 
   pCsr->aOffset[iOut] = iInput;
   U8_NEXT(zInput, iInput, nInput, c); 
@@ -138179,7 +137353,7 @@ static int icuNext(
 
     while( iStart<iEnd ){
       int iWhite = iStart;
-      U8_NEXT(pCsr->aChar, iWhite, pCsr->nChar, c);
+      U16_NEXT(pCsr->aChar, iWhite, pCsr->nChar, c);
       if( u_isspace(c) ){
         iStart = iWhite;
       }else{